簡體   English   中英

如何使用AWK根據兩個文件之間的公共字段刪除一個文件上的重復行?

[英]How to delete duplicated rows on one file based on a common field between two files with AWK?

我有兩個檔案

  1. 文件1包含3個字段

  2. 文件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中使用進程替換以及joinsort實用程序:

join -v 2 <(sort file_1) <(sort file_2)

如果您使用的是不帶進程替換的外殼,則必須對文件進行預排序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM