Frage

Ich habe einige Daten auf einer einzigen Zeile wie unten

abc edf xyz rfg yeg udh

Ich möchte die Daten wie unten

präsentieren
abc
xyz
yeg


edf
rfg
udh

, so dass abwechselnde Felder mit gedruckten Neuen-Zeile getrennt. Gibt es einen Liner für das?

War es hilfreich?

Lösung

Das folgende awk Skript kann es tun:

> 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

Andere Tipps

Python im gleichen Geist wie die oben awk (4 Zeilen):

$ 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-Liner (Weglassen des Rohrs, um es die identisch ist):

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

Eine weitere Perl-5-Version:

#!/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;

Schade, dass die bisherigen Perl Antworten so lang sind. Hier sind zwei Perl-Einzeiler:

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

Bei älteren Versionen von Perl (ohne "sagen"), können Sie diese verwenden:

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

Nur zum Vergleich, hier ein paar Perl-Skripte es (TMTOWTDI, nachdem alle) zu tun. Ein eher funktionaler Stil:

#!/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";

Wir könnten auch tun es näher an den AWK-Skript:

#!/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;

Ich habe aus Wege laufen, es zu tun, so dass, wenn andere kluge Perlers mit einem anderen Verfahren kommen, fühlen sich frei, um es hinzuzufügen.

Eine weitere Perl-Lösung:

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], '');
}

Sie könnten sogar verdichten es zu einem echten Einzeiler:

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], "");'

Hier ist die allzu wörtliche, nicht skalierbare, ultrakurze awk Version:

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

Etwas länger (zwei Zeichen), mit verschachtelten Schleifen (drucken eine zusätzliche Newline am Ende):

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

Ist eine zusätzliche Newline nicht gedruckt:

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

Zum Vergleich: paxdiablo 's-Version mit allen unnötigen Zeichen entfernt (1, 9 oder 11 mehr Zeichen):

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

Hier ist eine All-Bash-Version:

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

Mein Versuch in Haskell:

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>

Sie könnten auch nur tr verwenden: echo "abc edf xyz rfg yeg udh" | tr ' ' '\n'

Ruby-Versionen zum Vergleich:

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

Für Zeilenumbrüche, ich überlasse es Ihnen selbst zu tun.

Hier ist noch eine andere Art und Weise, mit Bash, manuell Wörter in einer Zeile neu ordnen - mit früheren Umwandlung in ein Array:

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 

Cheers!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top