awkコマンドループ

awkコマンドループ
awk '{print $1 ,": "  $3}' Src.txt | column -t
awk '{for(x=2;$x;++x) print $1, $x "\n"}'  Src.txt | column -t

このコマンドは機能しますが、フォーマットが正しくありません。最初と2番目の列のみを印刷したり、1番目の列を印刷してから2番目と3番目の列を印刷したりできますが、必要な結果は次のとおりです。

column 1 column 2
column 1 column 3
column 1 column 4 .....

例:

Col1  a b c
Col2  1 2 3  
col3  x y z

出力

Col1 a
Col2 b
Col3 c

Col1 b
col2 2
Col3 y

Col1 c
Col2 3
Col3 z

たぶん適切なループを追加する必要がありますか?

答え1

awkがどのように機能するかは、基本的に各項目を繰り返すことです。ワイヤーテキストを入力し、スペースで区切られた各項目をフィールドに分割します。この場合、関心のあるフィールドは$ 2、$ 3、および$ 4です。今、各行の各$ 2フィールドをリストに保存して印刷することができたらどうでしょうか。これが、配列が役に立つ可能性がある部分です。

awkコードの本文を1つの大きなwhileループと考えると、フィールド2、3、4を適切な配列に分割できます。配列は各行ごとに埋められます。したがって、行を繰り返すと、デフォルトですべてが列(配列)にソートされます。完了したら、「Column#」テキストを追加しながら、ループを介して各列(配列)を個別に印刷できます。

$ awk '{ array1[NR]=$2;array2[NR]=$3;array3[NR]=$4} END{for(i=1;i<=NR;i++){print "Column"i" "array1[i]};printf "\n";for(i=1;i<=NR;i++){print "Column"i" "array2[i]}; printf"\n"; for(i=1;i<=NR;i++){print "Column"i" "array3[i] };printf "\n" }' columns.txt           
Column1 a
Column2 1
Column3 x

Column1 b
Column2 2
Column3 y

Column1 c
Column2 3
Column3 z

もちろん、このように長い行は使用するのが少しぎこちないです。私たちはすべてをスクリプトに入れることができます:

#!/usr/bin/awk -f

{ array1[NR]=$2;array2[NR]=$3;array3[NR]=$4 } 

END{
  for(i=1;i<=NR;i++){
     print "Column"i" "array1[i]};printf "\n";
   for(i=1;i<=NR;i++){
     print "Column"i" "array2[i]}; printf"\n"; 
   for(i=1;i<=NR;i++){
     print "Column"i" "array3[i] };printf "\n" 
}

スクリプトを呼び出してcolumnate.awk権限を実行可能に変更したら、chmod +x columnate.awkテキストファイルを引数として実行します。

$ ./columnate.awk columns.txt                                                                                                                          
Column1 a
Column2 1
Column3 x

Column1 b
Column2 2
Column3 y

Column1 c
Column2 3
Column3 z

関連情報