Bash

基於共同的兩列連接兩個表,如果不匹配,則添加 NA 或空值

  • August 25, 2021

我想像這樣合併兩個表

表格1

Chr1 5
Chr1 10
Chr1 20
Chr2 10
Chr2 30

表_2

Chr1 10 value value2
Chr1 20 value value2
Chr2 30 value value2

期望的輸出

Chr1 5
Chr1 10 value value2
Chr1 20 value value2
Chr2 10
Chr2 30 value value2

我在 awk 中找到了用於合併表的腳本,這些表僅保留與兩個表中的兩列匹配的行。但是在這裡,我想要 Table_1 的所有行,但如果它們匹配,則添加 Table_2 的值。你能告訴我如何實現這一目標嗎?

$ awk '{k=$1 FS $2} NR==FNR{map[k]=$0; next} {print (k in map ? map[k] : $0)}' table2 table1
Chr1 5
Chr1 10 value value2
Chr1 20 value value2
Chr2 10
Chr2 30 value value2
$ awk '{ key = $1 FS $2 };
      NR == FNR { t[key] = $0; next };
      key in t { print t[key]; next };
      1' table2.txt table1.txt
Chr1 5
Chr1 10 value value2
Chr1 20 value value2
Chr2 10
Chr2 30 value value2
  • 在讀取的每個輸入行上(對於讀取的兩個文件),變數key都設置為前兩個欄位($1$2),它們之間有欄位分隔符(FS)。 FS被使用是因為它是唯一保證不在任何一個欄位中的字元),所以是唯一保證生成唯一鍵的字元。此鍵用作名為 的關聯數組的索引t
  • 當它讀取時table2.txt必須在命令行上列為第一個文件名 arg),每個輸入行都儲存在t數組的一個元素中。

如果table2.txt包含重複的條目——即前兩個欄位相同的多行——它只會記住最後一個看到的條目。如果您希望它記住所有這些重複項(按照它們出現的順序),請將 awk 腳本的第二行更改為:

NR == FNR { if (key in t) { t[key] = t[key] "\n" $0 } else { t[key] = $0 }; next };
  • 當它讀完第一個文件時,它讀入table1.txt(第二個文件名 arg)並列印數組中的相應條目(table2如果存在),否則列印目前行。
  • 腳本1最後一行的是慣用的 awk 簡寫- 值評估為真,當某些東西評估為真時的預設操作是列印目前行。awk``{print}``1

注意:如果table2.txt很大,這將使用大量 RAM。這在任何具有千兆字節 RAM 的現代系統上都不太可能成為問題。

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