Bash
使用 awk 辨識重複欄位並刪除兩者
以前,我問過這個問題:辨識重複欄位並使用 awk 列印兩者。
我有一個包含多列的文件,並且想要辨識重複特定列值(列 3-6)的行。
對此的回答是
awk 'n=x[$3,$4,$5,$6]{print n"\n"$0;} {x[$3,$4,$5,$6]=$0;}' file
我現在有一個問題,我想從數據文件中刪除使用上述程式碼標識的所有行,只留下從未重複的行。
我嘗試使用
!=
而不是,=
但這給出了與 = 相同的結果或返回 0 行。我也嘗試過:awk '!seen[$3, $4, $5, $6]++' file
但這也保留了我想要刪除的副本的第一個實例。
儘管您正在從 尋找解決方案
awk
,但如果您的預期結果是消除重複項而不一定是awk
單獨通過,請嘗試:
- 首先,確保對原始輸入文件進行排序,例如
sort unsorted_file > file
- 執行您之前發現的 awk 命令以辨識第 3-6 列中的重複項,並將輸出保存到文件中,例如
file_3-6_dupes
,在命令提示符下:$ awk 'n=x[$3,$4,$5,$6]{print n"\n"$0;} {x[$3,$4,$5,$6]=$0;}' file > file_3-6_dupes
- 最後,用於
comm
消除重複,將輸出保存到文件中,例如file_3-6_uniques
:$ comm -23 file file_3-6_dupes > file_3-6_uniques
這是如何工作的
- 排序輸入
file
是必要的,因為comm
只有排序輸入才能正常工作- 該
awk
命令不會改變它發現的重複項的出現順序,它只是遵循它們在原始文件中的任何順序,file
所以實際上它只是file
首先需要排序的原始文件- 預設
comm
輸出三列:僅在文件 1 中的行,僅在文件 2 中的行,以及公共行- 文件 1:
file
- 文件 2:
file_3-6_dupes
-number
選項指定comm
要抑制的輸出列,- 所以
-3
意味著,suppresscomm
的輸出第 3 列,什麼是常見的。file_3-6_dupes
它僅包含重複項,源自file
,因此這些重複項是唯一與file
和file_3-6_dupes
- 因為我們想要相反的結果,所以我們只是
-3
壓制常見的東西,它們是重複的- 順便說一句,我們不需要額外
-2
的東西來抑制僅在文件 2 中的東西,在我們的例子中沒有因此,通過結合使用
awk
、原始文件和comm
,我們可以實現您消除第 3-6 列重複行的目標。尖端
- 如果原始
file
文件來自 Windows,則非 Unix 行結尾可能會阻止comm
awk-generated 正常工作file_3-6_dupes
,因此如果您發現無法正常工作,則可以繼續執行dos2unix
,然後重試這些步驟,那麼它應該可以工作file``comm