特定の出力フィールド区切り文字を使用して特定の列を印刷します。

特定の出力フィールド区切り文字を使用して特定の列を印刷します。
cat A.tsv
1,a,d
2,b,e
3,c,f
$ awk -F ',' -v OFS="," '{print $2, $3}' A.tsv 
a,d
b,e
c,f
  • 次の4つのコマンドが上記と同じ結果を提供すると予想しました。
$ awk 'FS=","; OFS=","; {print $2, $3}' A.tsv 
1,a,d
1,a,d
,
2,b,e
2,b,e
b,e
3,c,f
3,c,f
c,f
$ awk -F ',' 'OFS=","; {print $2, $3}' A.tsv 
1,a,d
a,d
2,b,e
b,e
3,c,f
c,f
$ awk -v OFS="," 'FS=","; {print $2, $3}' A.tsv 
1,a,d
,
2,b,e
b,e
3,c,f
c,f
$ awk -F ',' 'FS=OFS; {print $2, $3}' A.tsv 
1,a,d
a d
2,b,e
 
3,c,f

最後の4つのコマンドの結果が最初のコマンドと異なる理由を説明できる人はいますか?

引用:シェルスクリプトのawk -FSとawk -fの違い

答え1

awkプログラムは、TRUEと評価されたときに実行されるペアpattern {action}で構成されます。省略するとデフォルト値はTRUEと見なされ、省略するとデフォルト動作はTRUEです。{action}patternpattern{action}{print}

存在する

awk 'FS=","; OFS=","; {print $2, $3}' A.tsv

あなたは:

  1. FS=",",値として指定され、FS副作用としてTRUEと評価され、基本操作をトリガーするパターン{print}

  2. モードOFS=","も割り当てられ、,TRUEと評価され、2番目にOFS基本操作をトリガーします。{print}

  3. ジョブのモードがないため、{print $2,$3}デフォルト値を TRUE とし、ジョブがトリガーされます。ただし、最初のレコードが処理されるまで設定されていないため、両方とも空ですFS(awkはデフォルトのスペースを使用して最初のレコードを解析し、レコード全体を割り当てるため)。後続のレコードは、予想されるコンマ区切り値を出力します。,$2$3FS$1

おそらく、レコード処理が開始される前にジョブに合計をFS=","割り当てようとしますOFS=","。これがブロックが行うことですBEGIN

awk 'BEGIN{FS=","; OFS=","} {print $2, $3}' A.tsv

または

awk -F ',' 'BEGIN{OFS=FS} {print $2, $3}' A.tsv

あるいは、ファイル名引数の前に変数の代入を引数として渡すこともできます。これは、複数のファイルで作業し、各ファイルに異なるフィールド区切り文字を設定したい場合に便利です。

awk '{print $2, $3}' FS="," OFS="," A.tsv

関連情報