awkで区切り文字を使用してファイルを1行ずつ比較します。

awkで区切り文字を使用してファイルを1行ずつ比較します。

ファイル1:

abc|123|check
def|456|map
ijk|789|globe
lmn|101112|equator

ファイル2:

abc|123|check
def|456|map
ijk|789|equator
lmn|101112|globe

予想出力:

ijk|789|equator
lmn|101112|globe

現在のawkスクリプト:

awk 'BEGIN{OFS=FS="|"} NR==FNR{a[$3]=$3;next}!($3 in a)' file1 file2

これは配列の内容に基づいて比較されます。行ごとに比較して結果のみを印刷する方法です。

答え1

私が正しく理解した場合は、3番目のフィールドがfile1の対応するエントリと異なる場合は、file2から1行を印刷したいと思います。その場合は、次のことを行う必要があります。

awk 'BEGIN{FS="|"} NR==FNR{a[$1,$2]=$3;next}(a[$1,$2]!=$3)' file1  file2

$3あなたのキーは配列のキーで作成され、一意ではないので機能しません(両方とも両方のファイルaに存在します)。$3equatorglobe

grep私はこの特定のケースについてと両方が簡単であるという@drewbennのコメントに同意します。joinしかし、同じことを行うPerlメソッドは次のとおりです。

perl -laF'\|' -ne '($k{$F[0].",".$F[1]}||=$F[2]) eq $F[2]||print;' file1  file2

答え2

使いたいと思います。join(またはgrep -f)の代わりに。しかし、もしあなたが〜しなければならないawkを使用してください:

echo | awk '{system("join -v 2 file1 file2")}'

これは単にawkフロントエンドですjoin -v 2 file1 file2。もちろんgrep -v -f file1 file2

答え3

comm作業のための実際のツールは次のとおりです。

comm -13 file1 file2
ijk|789|equator
lmn|101112|globe

入力ファイルがまだソートされていない場合:

comm -13 <(sort file1) <(sort file2)

関連情報