[英]How to delete duplicated rows on one file based on a common field between two files with AWK?
我有兩個檔案
文件1包含3個字段
文件2包含4個字段
文件1的行數遠小於文件2的行數
我想使用以下操作在基於第一個字段的兩個文件之間進行比較
如果文件1的任何行的第一個字段出現在文件2的一行的第一個字段中,請不要為文件2打印該行。
任何建議將不勝感激。
Input File 1
S13109 3739 31082
S45002 3800 31873
S43722 3313 26638
Input File 2
S13109 3738 31081 0
S13109 3737 31080 0
S00033 3008 29985 0
S00033 3007 29984 0
S00022 4130 31838 0
S00022 4129 31837 0
S00188 3317 27372 0
S45002 3759 31832 0
S45002 3758 31831 0
S45002 3757 31830 0
S43722 3020 26345 0
S43722 3019 26344 0
S00371 3737 33636 0
S00371 3736 33635 0
Desired Output
S00033 3008 29985 0
S00033 3007 29984 0
S00022 4130 31838 0
S00022 4129 31837 0
S00188 3317 27372 0
S00371 3737 33636 0
S00371 3736 33635 0
awk 'FNR==NR{a[$1]++;next}!a[$1]' file1 file2
這個怎么運作:
FNR==NR
當您有兩個(或多個)要輸入到awk的輸入文件時, NR
將在下一個文件的第一行重置為1,而FNR
將從其中斷處繼續遞增。 通過檢查FNR==NR
我們實際上是在檢查是否當前正在解析第一個文件。
a[$1]++
如果我們要解析第一個文件(請參見上文),則創建一個以第一個字段$1
為鍵的關聯數組,並將值加1。這實際上使我們可以創建“可見”列表。
next
該命令告訴awk不要再處理任何其他命令,而是讀入下一條記錄並重新開始。 我們這樣做是因為file1僅用於設置關聯數組
!a[$1]
僅當FNR==NR
為false時才執行此行,即我們不解析file1,因此必須解析file2。 然后,我們使用file2的第一個字段$1
作為索引到先前創建的“可見”列表的索引。 如果返回的值為0,則意味着我們在file1中沒有看到它,因此我們應該打印此行。 相反,如果該值不為零,那么我們也看到它在文件1,因此,我們不應該打印出它的價值。 請注意, !a[$1]
等同於!a[$1]{print}
因為未給出默認動作是打印整行。
如果不需要保留行的順序,則可以在Bash,Korn Shell或Z Shell中使用進程替換以及join
和sort
實用程序:
join -v 2 <(sort file_1) <(sort file_2)
如果您使用的是不帶進程替換的外殼,則必須對文件進行預排序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.