使用Awk和match()

时间:2016-01-14 18:41:17

标签: bash awk

我有一个要分析的测序文件,它有很多行,如下面的制表符分隔行:

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等于。

2 个答案:

答案 0 :(得分:2)

您可以使用;tab作为字段分隔符。这样做,您可以访问$2中的DP=$14中的awk -F'[;\t]' '$2 ~ /33564../{sub(/DP=/,"",$14);print $14}' file.txt 字段中的数字:

sub

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

顺便说一句,如果您还将DP添加到字段分隔符集中,则21的值将位于字段awk -F'[;\t=]' '$2 ~ /33564../{print $21}' file.txt 中:

{{1}}

答案 1 :(得分:1)

在使用基因组数据后,我相信以下内容将比之前发布的解决方案更加强大。主要区别在于键值对被视为这样,没有任何关于它们的排序的假设等。次要差异是正则表达式中的克拉(“^”):

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;}
  }'

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

  import glob

  _contents = dict()
  for filename in glob.glob('*.csv'):
      file = open(filename, 'r')
      frd = file.readlines()
      _contents[filename]=frd

  for key in _contents:
     for other_key in _contents:
         if key == other_key:
             pass
         else:
            print("Comparing in between files {0} and {1}".format(key, other_key))
            non_identical_contents = set(_contents[key]) - set(_contents[other_key])
            print(list(set(_contents[key])-non_identical_contents))