あなたがperlにアレルギーがないことを願っています...
このソリューションは、任意の数の列を持つファイルに対して機能します。
$ perl -ne 'BEGIN { @a = (); } $i = 0; foreach (split(/\s+/)) { $l = ($a[$i++] ||= []); push @$l, $_; }; END { print join("\n", @$_) . "\n" foreach (@a); }' << EOF
> x1 y1 z1
> x2 y2 z2
> x3 y3 z3
> x4 y4 z4
> EOF
x1
x2
x3
x4
y1
y2
y3
y4
z1
z2
z3
z4
これは本当に明白ではないので、コメントします。
perl -n
行ごとに読み取り (正確には、読み取りと に対する分割$/
)、-e
スクリプトレットを実行します。
BEGIN
ブロックは最初の入力が読み取られる前に実行され、ブロックEND
は最後に実行されます。
解剖学:
BEGIN { @a = (); } # Creates an array named "a"
# Main scriptlet
$i = 0;
foreach (split(/\s+/)) { # Split an input line against one or more space chars
$l = # Set $l to...
($a[$i++] ||= []); # what is at index i of @a (increment i), but if not set,
# set to an (empty) array ref and return that
push @$l, $_; # Push token to the end of the array ref
}
END { # End block...
print join("\n", @$_) # Print the contents of array references, joined with \n,
. "\n" # then \n,
foreach (@a); # for each element of array a
} # DONE