كيف يمكنني تقسيم خط إعادة ترتيب العناصر ؟
سؤال
لدي بعض البيانات على خط واحد مثل أدناه
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
وهتاف!