次のテキストファイルがあります。
Doc_A 123 abc
Doc_A 456 def
Doc_A 789 ghi
Doc_B 123 abc
Doc_B 456 def
Doc_C 123 abc
Doc_C 456 def
Doc_C 789 ghi
Doc_C 101 jkl
と参考資料
Doc_A
Doc_B
Doc_C
Doc_D
Doc_E
Doc_F
参照ファイルの名前と一致するテキストファイルの最初の行を抽出し、その行を印刷するか、一致するものがない場合は、次のように特定の固定パターンを印刷したいと思います。
Doc_A 123 abc
Doc_B 123 abc
Doc_C 123 abc
Doc_D 10 20
Doc_E 10 20
Doc_F 10 20
以下のようにawkを使用して一致するパターンを印刷できます。要件に応じて固定された方法で見つからないパターンをどのように印刷できますか?
awk 'FNR == NR { a[$1] = 0; } FNR != NR { for (i in a) if ($0 ~ i && a[i]++ == 0) { print $0; break; } }' \ref.txt file.txt
ベストアンサー1
一致するものをルックアップ配列から削除し、最後に残ったものを印刷するのはどうですか?
$ awk 'NR==FNR {a[$1]; next}
$1 in a {print; delete a[$1]}
END {for (i in a) print i, "10 20"}
' ref.txt file.txt
Doc_A 123 abc
Doc_B 123 abc
Doc_C 123 abc
Doc_D 10 20
Doc_E 10 20
Doc_F 10 20
(awkは配列巡回順序を保証しません。問題がある場合)
説明する
その間、NR==FNR
私たちは最初の名前付きファイル(ref.txt
)に取り組んでいます。最初の(この場合は一意の)フィールドにインデックス付きの配列エントリを作成し、レコードに移動しますnext
。配列要素に値を割り当てる必要はありません。
それ以外の場合は、2番目の名前付きファイル()を処理していますfile.txt
。最初の列が参照ファイルで構成した配列と一致することを確認し、a
一致した場合はレコードを印刷します。$0
その後、アイテムを削除します。
除去は2つの目的に使用される。次回$1 in a
同じ項目をテストするとき、$1
答えは偽になるため、一致を「固有」にします。これは、file.txt
すべての行が処理された後でも、残りの要素がa
まだ一致していないことを意味します。END
これをブロックの「固定」形式で印刷できます。