【问题标题】:Using Awk and match()使用 awk 和 match()
【发布时间】:2016-01-14 18:41:16
【问题描述】:

我有一个要分析的序列文件,其中包含许多行,例如以下制表符分隔行:

chr12   3356475 .   C   A   76.508  .   AB=0;ABP=0;AC=2;AF=1;AN=2;AO=3;CIGAR=1X;DP=3;DPB=3;DPRA=0;EPP=9.52472;EPPR=0;GTI=0;LEN=1;MEANALT=1;MQM=60;MQMR=0;NS=1;NUMALT=1;ODDS=8.76405;PAIRED=0;PAIREDR=0;PAO=0;PQA=0;PQR=0;PRO=0;QA=111;QR=0;RO=0;RPP=9.52472;RPPR=0;RUN=1;SAF=3;SAP=9.52472;SAR=0;SRF=0;SRP=0;SRR=0;TYPE=snp GT:DP:RO:QR:AO:QA:GL    1/1:3:0:0:3:111:-10,-0.90309,0

我正在尝试使用 awk 将特定区域与其 DP 值匹配。这就是我正在尝试的方式:

awk '$2 == 33564.. { match(DP=) }' file.txt | head

匹配和通配符似乎都不起作用。

理想情况下,此代码将输出 3,因为这就是 DP 的含义。

【问题讨论】:

    标签: bash awk


    【解决方案1】:

    您可以使用;tab 作为字段分隔符。这样做您可以访问$2 中的号码和$14 中的DP= 字段:

    awk -F'[;\t]' '$2 ~ /33564../{sub(/DP=/,"",$14);print $14}' file.txt
    

    sub 函数用于从$14 中删除DP=,只留下值。

    顺便说一句,如果您还将= 添加到字段分隔符集,则DP 的值将在字段21 中:

    awk -F'[;\t=]' '$2 ~ /33564../{print $21}' file.txt
    

    【讨论】:

    • 感谢您的帮助。看起来 15 美元而不是 14 美元的效果很好。还有什么是-F 我在谷歌上搜索并找不到它。
    • 可能是我没有正确复制演示数据。改回14。关于-F,查看man awk! ;)
    【解决方案2】:

    在处理过基因组数据后,我相信以下解决方案将比之前发布的解决方案更可靠。主要区别在于键值对被这样对待,而不考虑它们的顺序等。次要区别是正则表达式中的克拉(“^”):

    awk -F'\t' '
      $2 ~ /^33564../ {
        n=split($8,a,";");
        for(i=1;i<=n;i++) {
          split(a[i],b,"=");
          if (b[1]=="DP") {print $2, b[2]} }}'
    

    如果要多次使用此脚本,那么最好抽象出查找功能,例如像这样:

    awk -F'\t' '
      function lookup(key, string,  i,n,a,b) {
         n=split(string,a,";");
         for(i=1;i<=n;i++) {
           split(a[i],b,"=");
           if (b[1]==key) {return b[2]}
         }
      }
      $2 ~ /^33564../ {
        val = lookup("DP", $8);
        if (val) {print $2, val;}
      }'
    

    【讨论】:

      猜你喜欢
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      • 2022-12-01
      • 2013-05-06
      • 2013-12-26
      • 2022-07-19
      • 2021-05-15
      • 1970-01-01
      相关资源
      最近更新 更多