根據 2 個檔案的 2 列中的字串連接行

根據 2 個檔案的 2 列中的字串連接行

我在 Linux 系統上有一個包含 3 列的 file1 和一個包含 4 列的 file2。如何根據 file1 第 3 列中的字串將兩個檔案連接到 file2 第 2 列中的字串? File2 是一個包含許多條目的大型資料庫。 file1 和 file2 的第 3 列和第 2 列分別隻共用很少的字串。我想輸出 file1 和連接的 file2 行,以防字串匹配,並為不匹配的條目輸出破折號。

文件1:

300 100 a101
450 410 a400
670 710 a20
700 610 a340

文件2:

b30  a340 tttttttt 456
b500 a200 llllllll 567
b60  a101 uuuuuuuu 344
b40  a50  kkkkkkkk 223

輸出:

300 100 a101 b60 a101 uuuuuuuu 344
450 410 a400 -
670 710 a20  -
700 610 a340 b30 a340 tttttttt 456

答案1

使用 GNUawk和 GNU join,這是 Linux 上的標準(可能會或可能不會與非 GNU 版本一起使用):

$ join -a1 -1 3 -2 2 <(sort -k3,3 file1) <(sort -k2,2 file2) | 
    awk '$4 == "" { $4 = "-" }; {t=$1; $1=$2; $2=$3; $3=t; print}' |
    sort
300 100 a101 b60 uuuuuuuu 344
450 410 a400 -
670 710 a20 -
700 610 a340 b30 tttttttt 456

join指令分別在欄位 3 和 2 上連接 file1 和 file2。它用流程替代確保兩個文件都按各自的關鍵字段排序。-a 1使用該選項可以file1列印來自 的所有行,即使它們與來自 的行不符file2

不幸的是,join將 file1 的關鍵欄位放在每個記錄的開頭。透過使用一個名為 $1 的值的臨時持有者的awk變數將欄位移回其原始順序來修復此問題。t如果檔案之間不匹配,awk 腳本也會在欄位 $4 中加入尾部破折號字元(因為join它本身不執行此操作)。

最後,對輸出進行排序。

相關內容