【问题标题】:Print the Search pattern in awk在 awk 中打印搜索模式
【发布时间】:2014-07-07 14:32:22
【问题描述】:

我想打印匹配的搜索模式,然后计算平均行。最好是一个例子:

输入文件:

chr17   41275978    41276294    BRCA1_ex02_01   278 
chr17   41275978    41276294    BRCA1_ex02_01   279 
chr17   41275978    41276294    BRCA1_ex02_01   280 
chr17   41275978    41276294    BRCA1_ex02_02   281 
chr17   41275978    41276294    BRCA1_ex02_02   282 
chr17   41275978    41276294    BRCA1_ex02_03   283 
chr17   41275978    41276294    BRCA1_ex02_03   284 
chr17   41275978    41276294    BRCA1_ex02_03   285 
chr17   41275978    41276294    BRCA1_ex02_04   286 
chr17   41275978    41276294    BRCA1_ex02_04   287 
chr17   41275978    41276294    BRCA1_ex02_04   288 

我想在 bash 循环中提取(例如)相同的第 4 列:

输出1:

chr17   41275978    41276294    BRCA1_ex02_01   278 
chr17   41275978    41276294    BRCA1_ex02_01   279 
chr17   41275978    41276294    BRCA1_ex02_01   280 

输出2:

chr17   41275978    41276294    BRCA1_ex02_02   281 
chr17   41275978    41276294    BRCA1_ex02_02   282 

输出3:

chr17   41275978    41276294    BRCA1_ex02_03   283 
chr17   41275978    41276294    BRCA1_ex02_03   284 
chr17   41275978    41276294    BRCA1_ex02_03   285 

以此类推。然后计算第 5 列的平均值很容易:

awk 'END{sum+=$5}{print NR/sum}' in_file.txt

在我的例子中,有数千行 BRCA1_exXX_XX - 所以有什么想法可以拆分它吗?

保罗。

【问题讨论】:

    标签: linux bash awk


    【解决方案1】:

    我认为这会满足您的需求。

    awk '{
        # Keep running sum of fifth column based on value of fourth column.
        v[$4]+=$5;
        # Keep count of lines with similar fourth column values.
        n[$4]++
    }
    
    END {
        # Loop over all the values we saw and print out their fourth columns and the sum of the fifth columns.
        for (val in n) {
            print val ": " v[val] / n[val]
        }
    }' $file
    

    【讨论】:

    • 永远不要使用字母l作为变量名,因为它看起来太像数字1。在某些字体中完全无法区分。
    • @EdMorton 够公平的。我用它来代表“线”,但这在那种情况下也没有多大意义。编辑。
    • 是的,太好了 - 它工作得非常好。谢谢你的解释!
    • 这会以随机顺序输出数据。
    • 假设您希望输出与输入的顺序相同,只需将n[$4]++ 移出当前操作部分并添加一个新的条件+操作!n[$4]++{ keys[++numKeys] = $4 },然后在结束部分for (k=1; k<=numKeys; k++) { val = keys[k]; print val ": " v[val] / n[val] }。正如您所提到的,只有最近的 GNU awk 版本允许您控制使用 in 运算符时选择的数组索引的顺序,但很少需要。
    【解决方案2】:

    假设条目按给定数据中的第 4 列排序,您可以这样做:

    awk '
    
      $4 != prev {              # if this line's 4th column is different from the previous line
        if (cnt > 0)            # if count of lines is greater than 0
          print prev, sum / cnt #   print the average
        prev = $4               # save previous 4th column
        sum = $5                # initialize sum to column 5
        cnt = 1                 # initialize count to 1
        next                    # go to next line
      }
    
      {
        sum += $5               # accumulate total of 5th column
        ++cnt                   # increment count of lines
      }
    
      END {
        if (cnt > 0)             # if count > 0 (avoid divide by 0 on empty file)
          print prev, sum / cnt  #   print the average for the last line
      }
    
    ' file
    

    【讨论】:

    • 这假定条目总是按顺序排列的。
    • 哇,它看起来可行:-) 谢谢!可以解释吗?我可以添加到第三列标准差值吗?
    • @EtanReisner 是的,它假定条目按第 4 列排序,如给定数据中一样。
    • 只需在 END 部分添加对 n 的测试,以避免在空文件上出现除零错误。
    猜你喜欢
    • 1970-01-01
    • 2016-01-04
    • 1970-01-01
    • 1970-01-01
    • 2014-04-25
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 1970-01-01
    相关资源
    最近更新 更多