【问题标题】:awk select and sum value from multiple columns based on delimiterawk 根据分隔符从多列中选择和求和值
【发布时间】:2016-10-05 23:37:17
【问题描述】:

我有一个包含数百万行和约 400 个制表符分隔列的大文件 (vcf)。为简洁起见,将列数很少的行粘贴在下面:

1/1:0,0,0:0:0,0,0,0    1/1:0,0,0:0:0,0,0,0     1/1:37,3,0:1:0,0,1,0    1/1:0,0,0:0:0,0,0,0

我想用分隔符: 分割每一列并打印第四组值(0,0,0,0 表示 col 1;0,0,0,0 表示 col 2;0,0, 1,0 表示第 3 列;依此类推)每列。

所以,期望的输出是:

Col1      Col2        Col3      Col4      ..   Coln
0,0,0,0   0,0,0,0     0,0,1,0   0,0,0,0   ..   a,b,c,d

这对于 awk 来说太疯狂了吗?我更喜欢在 awk 中执行此操作,因为我的文件在我们的 unix 服务器中。我可以在 R 中做到这一点,尽管我可以想象读取文件、拆分每列和处理等需要花费大量时间。所以我将不胜感激。谢谢。

可选:为了使这更困难,是否可以将四个值的前两个数字相加,并将四个值中的后两个相加得到 value1,value2 列?也许我要求太多了。对不起。在这种情况下,以下将是所需的输出:

Col1  Col2    Col3  Col4  ..   Coln 
0,0   0,0     0,1   0,0   ..   a+b,c+d

【问题讨论】:

  • 从第 10 列开始 - 为什么我必须滚动前 9 列才能看到牛肉?请只发布所需的部分作为输入和所需的输出。
  • @JamesBrown 好点。为清楚起见进行了编辑。谢谢。

标签: bash awk vcf-vcard


【解决方案1】:

awk 来救援!

$ awk '{for(i=1;i<=NF;i++) 
          {sub(/.*:/,"",$i); 
           split($i,a,","); 
           $i=a[1]+a[2] "," a[3]+a[4]}}1' file


0,0 0,0 0,1 0,0

添加列标题也不是那么难...

为制表符分隔的输出字段设置-v OFS='\t'

【讨论】:

  • 再次感谢您的救援!效果很好。您能否解释一下第二行{sub(/.*:/,"",$i);,以便我以后可以自己执行类似的任务?谢谢。
  • 知道了。对于所有列,将直到: 之前的任何内容都替换为空。然后第三行将其存储到数组 a 中。最后一行检索每个数组的元素并将它们相加。
  • 正确,因为正则表达式是贪婪的,它会替换到最后一个冒号,拆分最后一个元素并将相应的元素相加,覆盖现有字段以便可以委托打印。
【解决方案2】:
awk 'NR==1{
        for(i=1;i<=NF*2;i+=2){           #print first line because one column is become two column so NF*2
            printf "val"i"\tval"i+1"\t"
        }
        print "";
      } 
     {
        for(i=1;i<=NF;i++) {
        match($i,".*(.,.),(.,.)$",a);    #match function matches  first two numbers of the four values 
        printf a[1]"\t"a[2]"\t";         #and the last two of the four values
    }
    print "";
    }' file

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2015-06-03
    • 2018-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多