【问题标题】:nested for loops in awk to count number of fields matching values在 awk 中嵌套 for 循环以计算匹配值的字段数
【发布时间】:2015-05-01 19:06:48
【问题描述】:

我有一个包含两列(140 万行)的文件,如下所示:

CLM MXL
0 0
0 1
1 1
1 1
0 0
29 42
0 0
30 15

我想计算每个可能的值组合的实例;例如,如果有 x 行,其中 CLM 列等于 0,MXL 列匹配 1,我想打印:

0 1 x

由于 CLM 列的最大值为 188,MXL 列的最大值为 128,因此我尝试在 awk 中使用嵌套的 for 循环,如下所示:

awk '{for (i=0; i<=188; i++) {for (j=0; j<=128; j++) {if($9==i && $10==j) {print$0}}}}' 1000Genomes.ALL.new.txt > test

但这只会打印出原始文件,这是有道理的,我只是不知道如何正确编写一个 for 循环,为每个值组合打印出一个文件,然后我可以 wc 或打印出一个每个组合的计数文件。 awk、bash 脚本、perl 脚本中的任何解决方案都会很棒。

【问题讨论】:

    标签: loops awk


    【解决方案1】:

    1。纯awk 解决方案

    $ awk 'NR>1{c[$0]++} END{for (k in c)print k,c[k]}' file | sort -n
    0 0 3
    0 1 1
    1 1 2
    29 42 1
    30 15 1
    

    工作原理

    代码使用单个变量cc 是一个关联数组,其键是文件中的行,值是出现次数。

    • NR&gt;1{c[$0]++}

      对于除第一行(具有标题)之外的每一行,这都会增加该行中组合的计数。

    • END{for (k in c)print k,c[k]}

      这会打印出最终计数。

    • sort -n

      这只是为了美观:它将输出行按可预测的顺序排列。

    2。替代使用uniq -c

    $ tail -n+2 file | sort -n | uniq -c | awk '{print $2,$3,$1}'
    0 0 3
    0 1 1
    1 1 2
    29 42 1
    30 15 1
    

    工作原理

    • tail -n+2 file

      这将打印文件的第一行以外的所有内容。这样做的目的是删除列标题。

    • sort -n | uniq -c

      这会对行进行排序,然后计算重复项。

    • awk '{print $2,$3,$1}

      uniq -c 将计数放在首位,而您希望计数是最后一行。这只是将列重新排列为您想要的格式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多