ファイルが2つあります。
ファイル1:
abc|123|check
def|456|map
ijk|789|globe
lmn|101112|equator
ファイル2:
check
map
equator
globe
AWK関数は、file1の3番目の列(3番目の列を切り捨ててソートした後)をfile2のソートされた内容と比較する必要があります。
- すべての行が一致した場合は1を返す必要があります。
- それ以外の場合は2を返す必要があります。
答え1
function are_all_there {
local num_diff=$(comm -3 <(cut -d'|' -f3 "$1" | sort) <(sort "$2") | wc -l)
(( num_diff == 0 )) && return 1 || return 2
}
答え2
awk
あなたの意見によると、これは唯一の選択ではないようです。したがって、これはawkではない方法です。
あなたは必要性に言及していませんユニーク質問では比較しましたが、uniq
コメントの例では使用しました。必要でない場合ユニーク一致する場合は、ソートオプションを削除します-u
。 (でテスト済みbash
)。
(($(comm -3 <( cut -d'|' -f3 file1 | sort -u ) \
<( sort -u file2 ) | wc -l))) && echo 2 - not all match ||
echo 1 - all match
またはawk
-in を使用して最終比較を実行しますpaste
。
paste <( cut -d'|' -f3 file1 | sort -u ) \
<( sort -u file2 ) |
awk '$1!=$2{m=2; exit}
END{ if(m == 2){print "2 - not all match"; exit;}
print "1 - all match";}'
または、awk
2つの入力ファイルの比較
awk '{if(NR == FNR){a[NR]=$1}
else{ if($1 != a[NR]){m=2; exit}}}
END{ if(m == 2){print "2 - not all match"; exit;}
print "1 - all match";}' \
<( cut -d'|' -f3 file1 | sort -u ) \
<( sort -u file2 ) |
答え3
興味深いCSの答え!これは純粋なセット比較なので、実際には何も並べ替える必要はありません。
入力ファイルは、要素がペアで構成されるセットを表します。たとえば、で行がfoo
3回表示された場合は、file1
<、3>要素を意味しますfoo
。 3回file2
含まれると、両方のセットがfoo
その要素を含むことを意味します。繰り返し回数が異なるか含まれていfile2
ない場合は、セットに<、3>が含まれていないことを意味します。foo
foo
foo
また、<、3>などのペアセットは、キーを3にfoo
マップするハッシュとして表示できます。foo
TXR Lisp awkマクロ:
(awk (:begin (set fs "|"))
(:let (h1 (hash :equal-based)) (h2 (hash :equal-based)))
((= arg 1) (inc [h1 [f 2] 0]))
((= arg 2) (inc [h2 rec 0]))
(:end (exit (equal h1 h2))))
ファイルが所望の方法で同じであれば、成功した終了状態が生成され、そうでなければ失敗状態が生成される。
$txr comp.tl ファイル1 ファイル2 $エコ$? 0 $エコーマッピング>>ファイル2 $txr comp.tl ファイル1 ファイル2 $エコ$? 1
「1」または「2」の出力を解析して呼び出し元を複雑にするには、ルールを変更するだけです:end
。
(:end (prn (if (equal h1 h2) "1" "2")))
これは通常のawkの場合です。主な違いは、簡潔な構文があり、参照する変数を定義する必要がないことです。一方、2つの連想配列を比較して追跡する独自のarg
変数を生成するには、一対のループを作成する必要があります。私たちが作業しているファイルのうち(GNU AwkはARGIND
この目的に役立ちます。)
BEGIN { FS = "|" }
FNR == 1 { arg++ }
arg == 1 { h1[$3]++; }
arg == 2 { h2[$0]++; }
END { same = 1
for (i in h1)
if (h1[i] != h2[i]) {
same = 0
break
}
if (same)
for (i in h2)
if (h2[i] != h1[i]) {
same = 0
break
}
print same ? "1" : "2"; }