【问题标题】:How to write header names based on value in columns using awk如何使用awk根据列中的值编写标题名称
【发布时间】:2016-05-10 00:07:55
【问题描述】:

我有一个制表符分隔符输入文件,其中包含 >100 列,值范围为 0-30。下面是一个 6 列 4 行的示例输入文件。第一行是标题行。

ID      S1  S2  S3  S4  S5
CNV1    2   0   2   0   2
CNV2    6   2   2   2   1
CNV3    2   1   3   2   4

我需要将列创建为 0、1、2、3、4 和 >4,并使用与输入文件中列的值对应的标题名称填充列。示例输出如下所示:

Output:
ID       0         1        2          3    4   >4
CNV1    S2,S4             S1,S3,S5
CNV2               S5     S2,S3,S4               S1
CNV3               S2     S1,S4        S3   S5

非常感谢任何帮助。

【问题讨论】:

    标签: awk


    【解决方案1】:

    awk 来救援!

    $ awk -v OFS='\t' 'NR==1{split($0,h); print $1,0,1,2,3,4,">4"; next}
                            {delete a; 
                             for(i=2;i<=NF;i++) 
                               {if($i>4)$i=4; 
                                a[$i]=(($i in a)?a[$i]","h[i]:h[i])} 
                               printf "%s\t",$1; 
                               for(i=0;i<=NF;i++) printf "%s\t", (a[i]?a[i]:" "); 
                               print ""}' file
    
    ID      0       1       2       3       4       >4
    CNV1    S2,S4           S1,S3,S5
    CNV2            S5      S2,S3,S4                S1
    CNV3            S2      S1,S4   S3      S5
    

    【讨论】:

      【解决方案2】:

      试试这个版本,它可以处理任意数量的值和标题:

      awk '                     
      FNR==1 {for(i=2;i<=NF;i++) {headers[i]=$i}}
      FNR>1 {
        if (maxrow<FNR) { maxrow=FNR}
        rowheaders[FNR]=$1;
        for(i=2;i<=NF;i++) {
          if (maxvalue<$i) {maxvalue=$i}
          if(!values[$1,$i]) {
            values[$1,$i]=headers[i]
          } else {
            values[$1,$i]=values[$1,$i] "," headers[i]
          }
        }
      }
      END { for (i=2;i<=maxrow;i++) { for (j=0;j<=maxvalue;j++) { if (values[rowheaders[i],j] && maxlen<length(values[rowheaders[i],j])) { maxlen=length(values[rowheaders[i],j])}}} 
        printf("%" maxlen "s","ID"); for (i=0;i<=maxvalue;i++) { printf("%s%" maxlen  "s",OFS,i)}; printf("\n")
        for (i=2;i<=maxrow;i++) {
          printf ("%" maxlen "s",rowheaders[i])
          for (j=0;j<=maxvalue;j++) {
            if (!values[rowheaders[i],j]) {
              printf("%s%" maxlen "s",OFS," ")
            }
            else {
              printf("%s%" maxlen "s",OFS,values[rowheaders[i],j])
            }
          }
          printf("\n")
        }
      }'
      

      测试:

      $ awk '                     
      FNR==1 {for(i=2;i<=NF;i++) {headers[i]=$i}}
      FNR>1 {
        if (maxrow<FNR) { maxrow=FNR}
        rowheaders[FNR]=$1;
        for(i=2;i<=NF;i++) {
          if (maxvalue<$i) {maxvalue=$i}
          if(!values[$1,$i]) {
            values[$1,$i]=headers[i]
          } else {
            values[$1,$i]=values[$1,$i] "," headers[i]
          }
        }
      }
      END { for (i=2;i<=maxrow;i++) { for (j=0;j<=maxvalue;j++) { if (values[rowheaders[i],j] && maxlen<length(values[rowheaders[i],j])) { maxlen=length(values[rowheaders[i],j])}}} 
        printf("%" maxlen "s","ID"); for (i=0;i<=maxvalue;i++) { printf("%s%" maxlen  "s",OFS,i)}; printf("\n")
        for (i=2;i<=maxrow;i++) {
          printf ("%" maxlen "s",rowheaders[i])
          for (j=0;j<=maxvalue;j++) {
            if (!values[rowheaders[i],j]) {
              printf("%s%" maxlen "s",OFS," ")
            }
            else {
              printf("%s%" maxlen "s",OFS,values[rowheaders[i],j])
            }
          }
          printf("\n")
        }
      }' inputfile    
      
            ID        0        1        2        3        4        5        6
          CNV1    S2,S4          S1,S3,S5                                    
          CNV2                S5 S2,S3,S4                                  S1
          CNV3                S2    S1,S4       S3       S5                  
      

      【讨论】:

        猜你喜欢
        • 2019-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-10
        • 2017-06-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多