文件处理:合并多个具有不同列和行数的文件

时间:2019-07-17 11:34:41

标签: bash shell file

我有多个制表符删除的文件,其中只有前两列是公共的。我正在尝试将它们合并到一个选项卡中。

示例:

假设我们有3个文件(file1,file2,file3)要合并到file4中。

(行名和列名仅用于演示目的,不包含在任何文件中)

输入文件=>

文件1:2行(r1,r2),3列(c1,c2,c3)

    c1 c2 c3

r1  a  b  c 

r2  d  e  f 

文件2:3行(r3,r4,r5),3列(c1,c2,c4)

    c1 c2 c4 

r3  1  2  3 

r4  4  5  6 

r5  7  8  9 

文件3:1行(r6),4列(c1,c2,c5,c6)

    c1 c2 c5 c6 

r6  w  x  y  z 

输出文件=>

对于所有3个文件,前2列(c1,c2)具有相同的名称

文件4:

    c1 c2 c3 c4 c5 c6 

r1  a   b  c  -  -  - 

r2  d   e  f  -  -  - 

r3  1   2  -  3  -  - 

r4  4   5  -  6  -  - 

r5  7   8  -  9  -  - 

r6  w   x  -  -  y  z 

我想做的是:为每个文件添加所需的空列,以便所有文件具有相同的列数,然后用“ awk”对列进行重新排序,然后使用“ cat”将它们垂直堆叠。但是我不知道这是最好的方法还是有更有效的方法。

谢谢

1 个答案:

答案 0 :(得分:0)

以下基本上完成了任务。它实质上是建立一个矩阵entry,该矩阵由行和列的名称索引。

awk '(FNR==1) { 
        for(i=1;i<=NF;++i) { 
           if (!($i in columns)) { column_order[++cn] = $i; columns[$i] }
           c[i+1]=$i
        }
        next
     }
     !($1 in rows) { row_order[++rn] = $1; rows[$1] }
     { for(i=2;i<=NF;++i) entry[$1,c[i]]=$i }
     END { 
        s="";for(j=1;j<=cn;++j) s=s OFS column_order[j]; print s
        for(i=1;i<=rn;++i) {
           row_name=row_order[i]
           s=row_name
           for(j=1;j<=cn;++j) {
              col_name = column_order[j]
              s=s OFS ((row_name,col_name) in entry ? entry[row_name,col_name] : "-")
           }
           print s
        }
     }' file1 file2 file3 file4 ... filen