Bash
基於共同的兩列連接兩個表,如果不匹配,則添加 NA 或空值
我想像這樣合併兩個表
表格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 的現代系統上都不太可能成為問題。