パイプライン区切りファイルの5番目の列に一致する項目を見つける

パイプライン区切りファイルの5番目の列に一致する項目を見つける
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|

列5のfile1とfile2で一致するレコードを見つける必要があります。したがって、上記から出力を返す必要があります。

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最初のファイルを解析し、file15番目の列をすべて抽出します。その後、これらの値はリストとして使用され、grep一致する項目を含む2番目のファイルのすべての行が印刷されます。

この方法を使用する際の注意点

file1この方法はの5番目の列と一致しますfile2

方法#2:ちょうどああない

過去にこの現場で使用されていた別の方法は、awkFNR施設を利用することです。ここでは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|

この方法を使用する際の注意点

この方法では、各Eメールアドレスの単一のインスタンスのみを処理できますfile1。したがって、列5に同じ値の行が2つある場合は区別できません。 OPが要求する内容を考慮すると、これは許可されているようです。

購読と並べ替え

joinこれを行うには、とを使用することもできますsort

$ join -t '|' -j 5  <(sort -k5,5 file2) <(sort -k5,5 file1) | sed 's/||.*//'

これにより、区切り文字が使用され、ソートされたファイルが|5番目の列にリンクされます。このメソッドはfile1sumから一致を印刷するため、file2これを使用してsed2番目の一致を最後から切り取ります。

はい

$ 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番目のフィールド(Perlの配列インデックスから始まる0)をハッシュキーとして保存$k{$F[4]}++し、その値を1ずつ増やします。フィールドを2番目に見ると、値は2になります。
  • スクリプトは両方のファイル(file1before)の各行を処理し、file25番目のフィールドが以前に表示された場合、つまり1より大きい場合は$k{$F[4]}その行を印刷します。

これは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 

答え3

ファイルサイズが似ている場合、最良の解決策は次のとおりです。sort両方のファイルが関心のある列に基づいてソートされ、joinその列の隣にあります。ファイルサイズがある場合、N漸近的Mな実行時間はですO(N*log(N)+M*log(M))

ファイルの1つが他のファイルよりもはるかに小さい場合は、O(N*M)他の答えの解決策がより良いです。

関連情報