Text-Processing

按第一列合併多個文件

  • March 10, 2021

我的問題與此類似:Merge multiple columns based on the first column values

我有多個文件(10+)要合併/加入一個輸出文件,例如:

文件 1

2000 0.0202094
2001 0.0225532
2002 0.02553
2003 0.0261099
2006 0.028843

文件 2

2000 0.0343179
2003 0.039579
2004 0.0412106
2006 0.041264

文件 3

2001 0.03
2004 0.068689
2006 0.0645474

所有文件都有相同的兩列並且長度不等。如果列沒有條目(一個或多個文件中缺少),我想要一個 1。如果任何文件(如 2005)中沒有條目,我不想要任何輸出。

所需的輸出將是:

       file1       file2       file3
2000    0.0202094   0.0343179   1
2001    0.0225532   1           0.03
2002    0.02553     1           1
2003    0.0261099   0.0395799   1
2004    1           0.0412106   0.0686893
2006    0.028843    0.041264    0.0645474

我試圖修改這個其他問題的答案提供的 awk 程式碼,但我覺得用那個解決方案是不可能的。

使用join

join -a1 -a2 -e 1 -o auto <(join -a1 -a2 -e 1 -o auto file1 file2) file3

人加入

-a FILENUM

還從文件 FILENUM 中列印不可配對的行,其中 FILENUM 為 1 或 2,對應於 FILE1 或 FILE2

-e EMPTY
用 EMPTY 替換缺少的輸入欄位

-o FORMAT

在構造輸出行時服從 FORMAT

如果 FORMAT 是關鍵字“auto”,則每個文件的第一行確定每行輸出的欄位數。

注意:加入需要排序的輸入,所以如果那些沒有排序(它們在給定的樣本中),首先對它們進行排序,例如:

join -a1 -a2 -e 1 -o auto \
   <(join -a1 -a2 -e 1 -o auto <(sort file1) <(sort file2)) \
   <(sort file3)

要將其應用於多個文件:

  1. 加入前兩個文件並將輸出保存到第三個文件說*join.tmp*:
join -a1 -a2 -e 1 -o auto file1 file2 >join.tmp
  1. next 循環遍歷其余文件並*join.tmp*為每次執行更新文件:
for file in rest_files*; do
   join -a1 -a2 -e 1 -o auto join.tmp "$file" >join.tmp.1
   mv join.tmp.1 join.tmp
done
  1. 最後,您*join.tmp*將成為您最終的加入結果。

帶標題列印:

$ hdr() { awk 'FNR==1{ print "\0", FILENAME }1' "$1"; }
$ join -a1 -a2 -e 1 -o auto \
     <(join -a1 -a2 -e 1 -o auto <( hdr file1) <(hdr file2)) \
     <(hdr file3) |tr -d '\0'

對於多文件版本:

$ hdr() { awk 'FNR==1{ print "\0", FILENAME }1' "$1"; }
$ join -a1 -a2 -e 1 -o auto <(hdr file1) <(hdr file2) >join.tmp
$ for file in rest_files*; do
    join -a1 -a2 -e 1 -o auto join.tmp <(hdr "$file") >join.tmp.1
    mv join.tmp.1 join.tmp
 done
$ tr -d '\0' <join.tmp >final.file

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