web-dev-qa-db-ja.com

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

file1:

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

file2:

_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

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

4
user1502952

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

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

配列aのキーとして$3を使用していて、$3が一意ではないため(equatorglobeの両方が両方のファイルに存在します)。

私は@drewbennに同意します。この特定のケースでは、grepjoinの両方が単純ですが、同じことを行うPerlの方法は次のとおりです。

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

代わりに join (またはgrep -f)を使用したいと思います。しかし、mustがawkを使用する場合:

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

これはjoin -v 2 file1 file2の単なるawkフロントエンドです。同様に、もちろん、grep -v -f file1 file2を使用できます。

5
user4443

comm は、このジョブの実際のツールです。

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

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

comm -13 <(sort file1) <(sort file2)
5
glenn jackman