2つのファイルを比較して、ID番号が一致するレコードのみを印刷し、重複レコードを印刷しないようにします。
2つのファイルがあります。
file1.txt
含む:
Simons 0987768798980
West 09809867678
Vickers 768774564650
Simons 76867790987
Peterson 24346576865
Simons 76867790987
Holister 87879655456
Peterson 87686765766
そして以下file2.txt
を含みます:
768774564650 Harry
76867790987 Steve
0987768798980 Mary
0987768798980 Mary
76856009097 Ali
87879655456 Rick
87686765766 Martin
必要な結果は次のとおりです。
Harry Vickers 768774564650
Steve Simons 76867790987
Mary Simons 0987768798980
Rick Holister 87879655456
Martin Peterson 87686765766
私が試したことは次のとおりです。
ARGV[1]==FILENAME{id2lastname[$2]=$1;id2id[$2]=$2}
ARGV[2]==FILENAME{id2firstname[$1]=$2}
$1 in id2id{print id2firstname[$1],id2lastname[$1],id2id[$1],id2firstname[$1]="",id2id[$1]="",id2lastname[$1]=""}
次の出力が生成されます。
Harry Vickers 768774564650
Steve Simons 76867790987
Mary Simons 0987768798980
Mary
Rick Holister 87879655456
Martin Peterson 87686765766
重複記録の姓、住民登録番号は削除されたが、名前はそのまま維持された理由を知りたいです。
このテクニックがおかしくなったり、フレームに巻き込まれなかったらすみません。私は長い間勉強していませんでした。
私の試みで問題が解決しない場合、またはより良い方法があると思われる場合は、他の方法で目的の結果を得ることができてうれしいですが、次のようにしてください。
- GAWKを使用しながら(続けて使いたいから)
- 簡単に保つようにしてください。
- そして、それがどのように機能するかを説明すると、何かを学ぶことができます。
ベストアンサー1
部分行が印刷される理由は、コードから配列から削除する値を削除するのではなく、その値を空の文字列に置き換えるためです。
これにより、チェックは空の文字列値$1 in id2id{ ... }
として評価されます。true
解決策はコードを次に置き換えることです。id2id[$1]=""
その後、delete id2id[$1]
期待どおりに動作します。
以下は少し単純化されたコードバージョンです。
awk 'NR == FNR { a[$2] = $1; next }
$1 in a { print a[$1], $2, $1; delete a[$1] }' file1.txt file2.txt
一行で:
awk 'NR==FNR{a[$2]=$1;next} $1 in a{print a[$1],$2,$1; delete a[$1]}' file1.txt file2.txt
Joinの代わりにawkを使用すると、シンプルさとカスタマイズが簡単であるという利点があります。
欠点は、マージ前の最初のファイルがRAMに保存されるため、大容量ファイルを効率的に処理できないことです。