سؤال

لدي بعض البيانات على خط واحد مثل أدناه

abc edf xyz rfg yeg udh

أريد أن أقدم البيانات على النحو التالي

abc
xyz
yeg


edf
rfg
udh

بحيث البديل المجالات تطبع مع السطر فصل.هل هناك أي أحد المتشددين من أجل هذا ؟

هل كانت مفيدة؟

المحلول

والسيناريو awk التالية يمكن أن تفعل ذلك:

> echo 'abc edf xyz rfg yeg udh' | awk '{
    for (i = 1;i<=NF;i+=2){print $i}
    print "";
    for (i = 2;i<=NF;i+=2){print $i}
    }'
abc
xyz
yeg

edf
rfg
udh

نصائح أخرى

وبيثون بنفس الروح كما AWK أعلاه (4 خطوط):

$ echo 'abc edf xyz rfg yeg udh' | python -c 'f=raw_input().split()
> for x in f[::2]: print x
> print
> for x in f[1::2]: print x'

وبيثون 1 بطانة (إهمال الأنابيب إليه وهو مطابق):

$ python -c 'f=raw_input().split(); print "\n".join(f[::2] + [""] + f[1::2])'

وآخر نسخة بيرل 5:

#!/usr/bin/env perl
use Modern::Perl;
use List::MoreUtils qw(part);

my $line = 'abc edf xyz rfg yeg udh';

my @fields = split /\s+/, $line; # split on whitespace

# Divide into odd and even-indexed elements
my $i = 0;
my ($first, $second) = part { $i++ % 2 }  @fields;

# print them out
say for @$first;
say '';          # Newline
say for @$second;

وعار أن الإجابات بيرل السابقة طويلة جدا. وهنا اثنين من بيرل واحد المتشددين:

echo 'abc edf xyz rfg yeg udh'|
  perl -naE '++$i%2 and say for @F; ++$j%2 and say for "",@F'

في الإصدارات القديمة من بيرل (بدون "ويقول")، يمكنك استخدام هذا:

echo 'abc edf xyz rfg yeg udh'|
  perl -nae 'push @{$a[++$i%2]},"$_\n" for "",@F; print map{@$_}@a;'

وفقط للمقارنة، وهنا عدد قليل من مخطوطات بيرل للقيام بذلك (TMTOWTDI، بعد كل شيء). وثمة أسلوب عملي إلى حد ما:

#!/usr/bin/perl -p

use strict;
use warnings;

my @a = split;
my @i = map { $_ * 2 } 0 .. $#a / 2;
print join("\n", @a[@i]), "\n\n",
      join("\n", @a[map { $_ + 1 } @i]), "\n";

ويمكننا أيضا أن تفعل ذلك أقرب إلى السيناريو AWK:

#!/usr/bin/perl -p

use strict;
use warnings;

my @a = split;
my @i = map { $_ * 2 } 0 .. $#a / 2;
print "$a[$_]\n" for @i;
print "\n";
print "$a[$_+1]\n" for @i;

ولقد نفدت من الطرق للقيام بذلك، لذلك إن وجدت Perlers ذكية أخرى تأتي مع طريقة أخرى، لا تتردد في إضافته.

وحل آخر بيرل:

use strict;
use warnings;

while (<>)
{
    my @a = split;
    my @b = map { $a[2 * ($_%(@a/2)) + int($_ / (@a /2))]  . "\n" } (0 .. @a-1); 
    print join("\n", @a[0..((@b/2)-1)], '', @a[(@b/2)..@b-1], '');
}

ويمكنك حتى أن تتكثف قبل أن تتحول إلى واقع واحد بطانة:

perl -nwle'my @a = split;my @b = map { $a[2 * ($_%(@a/2)) + int($_ / (@a /2))]  . "\n" } (0 .. @a-1);print join("\n", @a[0..((@b/2)-1)], "", @a[(@b/2)..@b-1], "");'

وهنا أيضا الحرفي غير قابلة فائقة قصيرة awk الإصدار:

awk '{printf "%s\n%s\n%s\n\n%s\n%s\n%s\n",$1,$3,$5,$2,$4,$6}'

أطول قليلا (اثنين من أكثر الشخصيات) ، وذلك باستخدام حلقات متداخلة (يطبع فواصل أسطر إضافية في النهاية):

awk '{for(i=1;i<=2;i++){for(j=i;j<=NF;j+=2)print $j;print ""}}'

لا الطباعة إضافية السطر:

awk '{for(i=1;i<=2;i++){for(j=i;j<=NF;j+=2)print $j;if(i==1)print ""}}'

وعلى سبيل المقارنة ، paxdiablo's الإصدار مع كافة الأحرف غير الضرورية إزالتها (1, 9 او 11 حرفا):

awk '{for(i=1;i<=NF;i+=2)print $i;print "";for(i=2;i<=NF;i+=2)print $i}'

هنا الكل باش الإصدار:

d=(abc edf xyz rfg yeg udh)
i="0 2 4 1 3 5"
for w in $i
do
    echo ${d[$w]}
    [[ $w == 4 ]]&&echo
done

ومحاولة مني في هاسكل:

Prelude> (\(x,y) -> putStr $ unlines $ map snd (x ++ [(True, "")] ++ y)) $ List.partition fst $ zip (cycle [True, False]) (words "abc edf xyz rfg yeg udh")
abc
xyz
yeg

edf
rfg
udh
Prelude>

ويمكنك أيضا أن مجرد استخدام آر: echo "abc edf xyz rfg yeg udh" | tr ' ' '\n'

والإصدارات روبي للمقارنة:

ARGF.each do |line|
  groups = line.split
  0.step(groups.length-1, 2) { |x| puts groups[x] }
  puts
  1.step(groups.length-1, 2) { |x| puts groups[x] }
end

ARGF.each do |line|
  groups = line.split
  puts groups.select { |x| groups.index(x) % 2 == 0 }
  puts
  puts groups.select { |x| groups.index(x) % 2 != 0 }
end
$ echo 'abc edf xyz rfg yeg udh' |awk -vRS=" " 'NR%2;NR%2==0{_[++d]=$0}END{for(i=1;i<=d;i++)print _[i]}'
abc
xyz
yeg
edf
rfg
udh

على أسطر, أترك لك أن تفعل بنفسك.

وهنا هو طريقة أخرى، وذلك باستخدام باش، لإعادة ترتيب يدويا الكلمات في خط - مع تحويل السابق لصفيف:

echo 'abc edf xyz rfg yeg udh' | while read tline; do twrds=($(echo $tline)); echo -e "${twrd[0]} \n${twrd[2]} \n${twrd[4]} \n\n ${twrd[1]} \n${twrd[3]} \n${twrd[5]} \n" ; done 

وهتاف!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top