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 列的文件 1 和文件 2 中找到匹配的記錄。
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
提取所有第五列。然後將這些值用作 的列表grep
,它將列印第二個文件中包含任何匹配項的行。
使用此方法的注意事項
file1
此方法將匹配中出現的任何第五列file2
。
方法#2:只需 awk
過去該地點使用的另一種方法是使用 的awk
FNR 設施。這裡awk
將迭代 2 個文件,逐行遍歷第二個文件,找出第一個文件中的每一行。
像這樣的方法就可以做到。將以下內容放入文件中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|
使用此方法的注意事項
此方法只能處理來自 的每個電子郵件地址的單一實例file1
。因此,如果有 2 行的第 5 列值相同,則無法區分它們。考慮到您在 OP 中的要求,這似乎是可以接受的。
加入並排序
您也可以使用join
和來執行此操作sort
。
$ join -t '|' -j 5 <(sort -k5,5 file2) <(sort -k5,5 file1) | sed 's/||.*//'
這將使用分隔符號|
並將排序後的檔案連接到第五列。這種方法會列印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'\|'
設定 to 的欄位分隔-a
符號|
。- 對於處理的每一行,將第 5 個欄位(在 Perl 中從陣列索引開始
0
)儲存為雜湊鍵($k{$F[4]}++
並將其值遞增 1。第二次看到某個欄位時,該值將為 2。 - 該腳本將處理兩個文件的每一行(
file1
beforefile2
),如果之前已經看到第 5 個字段,即 if$k{$F[4]}
大於 1,則列印該行。
這假設第五列在相同的文件。如果情況並非如此,並且某些列可能在同一文件中重複,請改用:
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