首页 > 解决方案 > 文件处理:组合具有不同列数和行数的多个文件

问题描述

我有多个制表符分隔文件,其中只有前两列是共同的。我正在尝试将它们组合在一个制表符分隔的文件中。

示例:假设我们有 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”将它们垂直堆叠。但我不知道这是最好的方法还是有更有效的方法。

谢谢,

标签: bashshellfile

解决方案


以下基本上完成了任务。它本质上建立了一个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 

推荐阅读