入力:
注:タブで区切られた2つの列、列2の単語を区切る通常のスペース。
1 the mouse is dead
2 hit the wall
3 winter lasts forever
必要な出力:
1 the
1 mouse
1 is
1 dead
2 hit
2 the
2 wall
3 winter
3 lasts
3 forever
awk
はこれを実現する方法ですか?
最初のフィールドは$1
で、NF
は行のフィールド数を保持し、$i
でフィールドにアクセスできます。ここで、i
は変数であり、ループはCとほぼ同じように機能します。
$ awk '{for (i = 2; i <= NF; i++) printf "%s\t%s\n", $1, $i} ' < blah
1 the
1 mouse
...
(これは、フィールド区切り文字としてのスペースとタブを区別しません。)
GNU sed
:
sed -E 's/^((\S+\s+)\S+)\s+/&\n\2/;P;D'
POSIX sed
構文では見苦しいです:
s='[[:space:]]\{1,\}' S='[^[:space:]]\{1,\}'
sed "s/^\(\($S$s\)$S\)$s/&\\
\2/;P;D"
別のawkのもの:
~$>echo '1 the mouse is dead
2 hit the wall
3 winter lasts forever
' | awk 'BEGIN { RS="[[:space:]]+"; } /^[[:digit:]]+$/ {line=$1; next}; { print line "\t" $1; }'
1 the
1 mouse
1 is
1 dead
2 hit
2 the
2 wall
3 winter
3 lasts
3 forever
少し良くレイアウトされています。
# split all parts into single Word records.
BEGIN { RS="[[:space:]]+"; }
# if the record is a number the save
/^[[:digit:]]+$/ { line=$1; next };
# else use last saved line number and this record to format output.
{ print line "\t" $1; }
Awkでsplit関数を使用することもできます。
awk -F"\t" 'BEGIN { OFS="\t" } { cols=split($2,arr," "); for ( i=1; i<=cols; i++ ) { print $1,arr[i] }}'