74

一度に複数の入力ファイルを AWK するための次のソリューションを投稿することで、多くの人が非常に役に立ちました。

$ awk 'FNR==NR{a[$1]=$2 FS $3;next}{ print $0, a[$1]}' file2 file1

これはうまくいきますが、誰かが私に理由を説明できるかどうか疑問に思っていましたか? 私は AWK 構文を理解するのが少し難しいと感じており、誰かが私のためにコード スニペットを分解することを気にしないことを望んでいました。

4

3 に答える 3

79
awk 'FNR==NR{a[$1]=$2 FS $3;next}

ここでは、最初の入力(file2)を処理します。たとえば、FSはスペースであり、array(a)を構築し、インデックスはcolumn1であり、値はcolumn2 " " column3平均FNR==NR and nextであり、コードのこの部分はfile2に対してのみ機能します。あなたは、NRとFNRが何であるかをgawkがチェックすることができます

{ print $0, a[$1]}' file2 file1

NR != FNR2番目の入力file1を処理するときです。ここでは、file1の行を出力し、column1をインデックスとして取得し、array(a)printで値を見つけます。つまり、file1とfile2は、両方のファイルでcolumn1によって結合されています。

NRとFNRについては、まもなく、

1st input has 5 lines
2nd input has 10 lines,

NR would be 1,2,3...15
FNR would be 1...5 then 1...10

FNR==NRあなたはチェックのトリックを見ます。

于 2013-02-20T16:16:41.157 に答える
13

Google でこの質問/回答を見つけましたが、別の質問 ( AWK を使用して 2 つのファイルをマージする方法) で見つかった非常に具体的なデータ セットを参照しているようです。以下は、私が探していた (ほとんどの人がそうだと思う) 答えです。つまり、単純に AWK を使用して 2 つの異なるファイルからすべての行を連結することです。joinpasteなどの UNIX ユーティリティを使用することもできますが、目的の出力が異なる場合、ifステートメントを使用するか、 OFSを変更することにより (ユーティリティによっては実行がより困難になる場合があります。以下を参照) たとえば、より表現力豊かな方法で出力を変更します (シェル スクリプト作成者にとって重要な考慮事項です)。

単純な行ごとの連結の場合:

awk 'FNR==NR { a[FNR""] = $0; next } { print a[FNR""], $0 }' file1 file2

これは、暗黙的な型変換を使用して、数値インデックス付き配列 (AWK には連想配列のみがあります) の機能をエミュレートします。比較的表現力があり、わかりやすい。

次の行で test1 と test2 という 2 つのファイルを使用します。

テスト1:

line one
line two
line three

テスト2:

line four
line five
line six

私はこの結果を得ます:

line one line four
line two line five
line three line six

出力の列間の値を結合する方法に応じて、適切な出力フィールド セパレータを選択できます。列を区切る省略記号 (...) の例を次に示します。

awk 'BEGIN { OFS="..."} FNR==NR { a[(FNR"")] = $0; next } { print a[(FNR"")], $0 }' test1 test2

この結果が得られます:

line one...line four
line two...line five
line three...line six

少なくとも、これが AWK のパワーを活用するきっかけになることを願っています!

于 2013-11-23T03:51:58.373 に答える