Bash

使用 awk 辨識重複欄位並刪除兩者

  • January 19, 2016

以前,我問過這個問題:辨識重複欄位並使用 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單獨通過,請嘗試:

  1. 首先,確保對原始輸入文件進行排序,例如sort unsorted_file > file
  2. 執行您之前發現的 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
  1. 最後,用於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,因此這些重複項是唯一與filefile_3-6_dupes
  • 因為我們想要相反的結果,所以我們只是-3壓制常見的東西,它們是重複的
  • 順便說一句,我們不需要額外-2的東西來抑制僅在文件 2 中的東西,在我們的例子中沒有

因此,通過結合使用awk、原始文件和comm,我們可以實現您消除第 3-6 列重複行的目標。

尖端

  • 如果原始file文件來自 Windows,則非 Unix 行結尾可能會阻止commawk-generated 正常工作file_3-6_dupes,因此如果您發現無法正常工作,則可以繼續執行dos2unix,然後重試這些步驟,那麼它應該可以工作file``comm

引用自:https://unix.stackexchange.com/questions/255963