私はあなたが間違っていると思います。あなたが持っているスクリプトは、インテリジェントなものを何も出力しません(a)。なぜなら、各行をに読み込もうとしている間$line
、実際にはそれらをに与えていないからawk
です。
次のような方法で、余分な(そして正しくない)ループを取り除くことができます。
awk -F'\t' '{ for (i=2; i<=NF; i++) print $1 "\t" $i "." }' ${file}
次のトランスクリプトに示されているように:
pax> echo 'A 1 2
...> B 3 4
...> C 5 6' >qq.in
pax> cat qq.in
A 1 2
B 3 4
C 5 6
pax> awk -F' ' '{ for (i=2; i<=NF; i++) print $1 " " $i "." }' qq.in
A 1.
A 2.
B 3.
B 4.
C 5.
C 6.
ご覧のとおり(タブではなくスペースを使用していますが)、これにより、希望する出力が得られます。
それがまだ機能していないというあなたの主張に応えて、私は違うことを懇願しなければならないのではないかと心配しています。次のトランスクリプト(タブ付き)は、アドバタイズされたとおりに機能することを示しています。
pax> cat qq.in
Excellent 29 54 47 46 38 22 50
Good 7 14 27 24 26 36 20
pax> awk -F'\t' '{ for (i=2; i<=NF; i++) print $1 "\t" $i; }' qq.in
Excellent 29
Excellent 54
Excellent 47
Excellent 46
Excellent 38
Excellent 22
Excellent 50
Good 7
Good 14
Good 27
Good 24
Good 26
Good 36
Good 20
それが実際にご使用の環境で機能していない場合、それは別の問題です。バギーawk
やその他の理由で失敗する可能性があります。
awk
まず、次のように、使用しているオペレーティングシステムのバージョンとオペレーティングシステムを把握します。
awk --version
uname -a
(a):実際には何かを出力しますが、ほぼ確実に期待したものではありません。実際に何が起こっているのかを実際に見てみましょう。オリジナルに類似した次のトランスクリプトを検討してください。
pax> ( echo 1; echo 2; echo 3 ) | while read line ; do
...> awk '{print "[" $0 "]"}'
...> done
[2]
[3]
今ではかなり奇妙に見えますが、最初の行を捨てているように見えます。
この理由は、while
との間の切断awk
です。はwhile
、標準入力から最初の行を読み取り、それをに割り当ててから$line
、セクションの本文を実行しdo..done
ます。
その本体はawk
入力ファイルがないため、標準入力から入力を受け取ります。
つまり、残りの標準入力ストリームを「吸い上げ」て処理します。
その後、ループに戻りwhile
ますが、標準入力のデータがなくなると、終了します。それはおそらく次のように説明したほうがよいでしょう。
pax> ( echo 1; echo 2; echo 3 ) | while read line ; do
...> echo "read: $line"
...> awk '{print "awk: " $0}'
...> done
read: 1
awk: 2
awk: 3
とを以下のセクションに実際に接続するwhile
と、正しく機能することがわかります。awk
echo "$line" |
pax> ( echo 1; echo 2; echo 3 ) | while read line ; do
...> echo "$line" | awk '{print "[" $0 "]"}'
...> done
[1]
[2]
[3]
もちろん、入力を1行に分割して、一度に1行に送信することはほとんど意味がありません。これは、複数の行を1つずつ完全に処理できるawk
場合です。awk
したがって、awk
この回答の最初のコードブロックに示されている1行のコマンドは、それを実行するためのより良い方法です。