Text-Processing

匹配兩個文件中的 column1-5 並列印匹配的 column1-5 以及 file1 的 column6&7 和 file2 的 column6

  • December 17, 2021

想要匹配 2 個文件中的第 1-5 列並列印第 1-5 列以及來自 file1 的第 6 和 7 列以及來自 file2 的第 6 列。兩個文件中不匹配的行也應該在不匹配的列中列印 NA 值

file1

12  800000  900000  66  73  0   0  
12  900000  1000000 73  48  2   2  
13  1000000 1100000 11  11  0   0  
12  1100000 1200000 12  12  0   0  
18  1400000 1600000 33  33  3   3  

file2

12  800000  900000  66  73  145(28.12)  
12  900000  1000000 73  48  703(51.17)  
13  1000000 1100000 11  11  545(43.99)  
12  1100000 1200000 12  12  699(45.30)
14  16100000    16200000    0   0   11(14.50)  
14  16200000    16300000    0   0   0    

Expected output

12  800000  900000  66  73  145(28.12)  0  0   
12  900000  1000000 73  48  703(51.17)  2  2  
13  1000000 1100000 11  11  545(43.99)  0  0  
12  1100000 1200000 12  12  699(45.30)  0  0  
14  16100000  16200000  0  0  11(14.50)  NA  NA 
14  16200000  16300000  0  0  0  NA  NA  
18  1400000 1600000 33  33  NA  3   3

我在 awk 命令下嘗試過,但沒有從兩個文件中獲取列

awk 'FNR==NR{A[$1 FS $2 FS $3 FS $4 FS $5]=$3;next}{print ($1 FS $3 FS $4 FS $5 in A ) ? $0 OFS A[$1 FS $3 FS $4 FS $5] : $0 OFS "NA"}' file1 file2

您的程式碼與您的描述不符,例如它正在儲存 $ 3 from file1 to print later but you say you want to print $ 4 和 $ 6, and then your expected output doesn’t match either of those and shows $ 6 和 $7 從 file1 代替。所以,只要按照你的預期輸出,我認為這就是你想要的:

$ cat tst.awk
{ key = $1 OFS $2 OFS $3 OFS $4 OFS $5 }
FNR==NR {
   file1[key] = $6 OFS $7
   next
}
{
   print $0, (key in file1 ? file1[key] : "NA" OFS "NA")
   delete file1[key]
}
END {
   for ( key in file1 ) {
       print key, "NA", file1[key]
   }
}
$ awk -f tst.awk file1 file2
12  800000  900000  66  73  145(28.12) 0 0
12  900000  1000000 73  48  703(51.17) 2 2
13  1000000 1100000 11  11  545(43.99) 0 0
12  1100000 1200000 12  12  699(45.30) 0 0
14  16100000    16200000    0   0   11(14.50) NA NA
14  16200000    16300000    0   0   0 NA NA
18 1400000 1600000 33 33 NA 3 3

請注意使用變數來保存兩個文件的鍵索引。當您有一個值組合的鍵時,不要嘗試在程式碼中多次編寫它,因為很容易出錯,就像您$2在處理 file2 時忘記包含在映射查找中一樣(您使用$1 FS $3 FS $4 FS $5 in A而不是$1 FS $2 FS $3 FS $4 FS $5 in Aand 在 ) 中再次做同樣的事情A[$1 FS $3 FS $4 FS $5]

另外-不要使用所有大寫的變數名(例如A)以避免與內置變數名發生衝突,如果沒有別的,請使用括號使您的程式碼更清晰,例如 idk if$1 FS $2 in A表示($1 FS) ($2 in A)(即$1 FS與查找結果的連接$2 in A)或($1 FS $2) in A(即查找 in 的串聯的結果$1 FS $2A或其他內容,但如果您只是將其寫為,($1 FS $2) in A那麼它是清晰明確的。

最後請注意,我使用OFS而不是FS作為數組索引分隔符 - 這是因為在程式碼中我們在END節中列印該值,並且應該分隔輸出欄位的東西是OFS,而不是FS。在這種情況下,它們都是相同的東西,一個空白字元,所以你不會看到區別,但是如果你想輸出 CSV 而不是我的程式碼,你需要做的就是添加-v OFS=','它,它會按原樣工作,而如果您FS在數組索引下標之間使用,那麼您需要更改它。

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