将来自不同文件的类似列合并到矩阵中

时间:2016-01-19 15:18:37

标签: shell matrix awk multiple-columns

我有以下格式的文件,每个文件在所有文件中都是通用的:

  File1.txt
  ID    Score            
  ABCD   0.9
  BCBS   0.2
  NBNC   0.67
  TCGS   0.8

  File2.txt
  ID    Score            
  ABCD   0.3
  BCBS   0.9
  NBNC   0.73
  TCGS   0.12

  File3.txt
  ID    Score            
  ABCD   0.23
  BCBS   0.65
  NBNC   0.94
  TCGS   0.56

我想合并所有文件的第二列(分数列),第一列是常用的,并显示文件名减去每个文件的扩展名作为标题,以确定分数来自何处矩阵看起来像

   ID     File1  File2 File3
  ABCD     0.9   0.3   0.23
  BCBS     0.2   0.9   0.65        
  NBNC     0.67  0.73  0.94          
  TCGS     0.8   0.12  0.56         

2 个答案:

答案 0 :(得分:4)

$ cat tst.awk
BEGIN { OFS="\t" }
FNR>1 { id[FNR] = $1; score[FNR,ARGIND] = $2 }
END {
    printf "%s%s", "ID", OFS
    for (colNr=1; colNr<=ARGIND; colNr++) {
        sub(/\..*/,"",ARGV[colNr])
        printf "%s%s", ARGV[colNr], (colNr<ARGIND?OFS:ORS)
    }
    for (rowNr=2; rowNr<=FNR; rowNr++) {
        printf "%s%s", id[rowNr], OFS
        for (colNr=1; colNr<=ARGIND; colNr++) {
            printf "%s%s", score[rowNr,colNr], (colNr<ARGIND?OFS:ORS)
        }
    }
}

$ awk -f tst.awk File1.txt File2.txt File3.txt
ID      File1   File2   File3
ABCD    0.9     0.3     0.23
BCBS    0.2     0.9     0.65
NBNC    0.67    0.73    0.94
TCGS    0.8     0.12    0.56

选择一些在输入中不会出现的字符串作为OFS,我使用了tab。

如果您没有GNU awk,请在脚本开头添加FNR==1{ ARGIND++ }

答案 1 :(得分:3)

另一种选择

$ awk 'NR==1{$0=$1"\t"FILENAME}1' File1 > all; 
  for f in File{2..6}; 
     do 
       paste all <(p $f) > temp && cp temp all; 
     done

将函数p定义为

p() { awk 'NR==1{print FILENAME;next} {print $2}' $1; }

我将您的数据复制到6个相同的文件File1..File6,并且脚本生成了这个。大部分工作是设置列名

ID      File1   File2   File3   File4   File5   File6
  ABCD   0.9    0.9     0.9     0.9     0.9     0.9
  BCBS   0.2    0.2     0.2     0.2     0.2     0.2
  NBNC   0.67   0.67    0.67    0.67    0.67    0.67
  TCGS   0.8    0.8     0.8     0.8     0.8     0.8