File 1:
Connect|20130320000023|UTC|PPP|[email protected]|[email protected]|0BCBE578|
File 2:
Connect|20130320000023|UTC|PPP|[email protected]|[email protected]|0BCBE578|
Connect|20130320000025|UTC|PPP|[email protected]|[email protected]|0BCBE578|
Connect|20130320000025|UTC|PPP|[email protected]|[email protected]|0BCBE578|
ファイル 1 とファイル 2 の両方の列 5 で一致するレコードを見つける必要があります。したがって、上記から出力を返す必要があります。
Connect|20130320000025|UTC|PPP|[email protected]|[email protected]|0BCBE578|
どうもありがとう、
答え1
方法 1: grep と awk
次のスニペットを使用してこれを実行できます:
$ grep -f <(awk -F '|' '{print $5}' file1) file2
Connect|20130320000025|UTC|PPP|[email protected]|[email protected]|0BCBE578|
詳細
を使用するビットはawk
、最初のファイルを解析し、file1
5 番目の列をすべて取り出します。これらの値は、 のリストとして使用されgrep
、2 番目のファイルで一致する行がすべて出力されます。
この方法の注意点
file1
このメソッドは、の5 番目の列の任意の出現に一致しますfile2
。
方法2: awkだけ
過去にこのサイトで使用されていた別のアプローチは、awk
の FNR 機能を使用することです。これは、 がawk
2 つのファイルを反復処理し、最初のファイルの各行に対して 2 番目のファイルを 1 行ずつ処理する場所です。
次のようなアプローチで実現できます。次の内容をファイルに記述しますcmds.awk
。
FNR == NR {
f1[$5] = $5
next
}
{ if ($5 == f1[$5]) print $0; }
これを次のように実行できます。
$ awk -F '|' -f cmds.awk file1 file2
注記:代わりにこのawk
パターンを使用することもできます:
FNR == NR {
f1[$5] = $5
next
}
{ if ($5 in f1) print $0; }
例
$ awk -F '|' -f s.awk file1 file2
Connect|20130320000025|UTC|PPP|[email protected]|[email protected]|0BCBE578|
この方法の注意点
このアプローチでは、 の各電子メール アドレスのインスタンスを 1 つだけ処理できますfile1
。したがって、5 番目の列に同じ値を持つ 2 つの行がある場合、この方法ではそれらを区別できません。ただし、OP の要件を考慮すると、これは許容できると思われます。
結合と並べ替え
join
およびを使用してこれを行うこともできますsort
。
$ join -t '|' -j 5 <(sort -k5,5 file2) <(sort -k5,5 file1) | sed 's/||.*//'
これはセパレータを使用し、ソートされたファイルを 5 列目に結合します。このアプローチはと|
の両方からの一致を出力するので、 を使用して2 番目の一致を末尾から切り取ります。file1
file2
sed
例
$ join -t '|' -j 5 <(sort -k5,5 file2) <(sort -k5,5 file1) | sed 's/||.*//'
[email protected]|Connect|20130320000025|UTC|PPP|[email protected]|0BCBE578
答え2
私はすべてを Perl で実行します:
$ perl -F'\|' -ane '$k{$F[4]}++; print if $k{$F[4]}>1' file1 file2
Connect|20130320000025|UTC|PPP|[email protected]|[email protected]|0BCBE578|
-a
配列への自動フィールド分割を有効にします@F
。-F'\|'
のフィールド区切り文字を に設定し-a
ます|
。- 処理される行ごとに、5 番目のフィールド (
0
Perl では配列インデックスは から始まります) をハッシュ キー ( として保存$k{$F[4]}++
し、その値を 1 ずつ増やします。フィールドが 2 回目に表示されたときは、その値は 2 になります。 - スクリプトは両方のファイルの各行を処理し (
file1
beforefile2
)、5 番目のフィールドが以前に見つかった場合 (つまり が$k{$F[4]}
1 より大きい場合)、その行を出力します。
これは、5番目の列が重複していないことを前提としています。同じファイル。そうでない場合、同じファイル内で一部の列が重複している可能性がある場合は、代わりに以下を使用します。
perl -e 'open(A,"$ARGV[0]"); while(<A>){@F=split(/\|/);$k{$F[4]}++;}
open(B,"$ARGV[1]"); while(<B>){@F=split(/\|/); print if $k{$F[4]}
}' file1 file2