仅获取具有特定字段的行

仅获取具有特定字段的行
#CHROM  POS     T1      T10     T11     T12     T13     T2      T3      T4      T5      T6      T106    T107    T108    T109    T110    T112    T114    T116    T120    T122    T125    T128    T129    T130
Aradu.A01       300806  H       B       B       B       B       B       B       B       H       B       B       H       B       B       B       B       B       B       B       B       B       B       B
Aradu.A01       386907  A       A       A       A       A       A       A       A       A       A       A       A       H       A       A       A       A       A       H       A       A       A       A
Aradu.A01       463100  B       B       A       A       A       A       A       H       B       A       A       H       H       H       H       H       B       A       B       A       H       H       A
Aradu.A01       471639  A       A       A       A       H       A       A       H       A       A       H       A       A       A       A       A       H       A       A       A       H       A       A
Aradu.A01       644024  H       B       B       B       B       B       B       B       H       H       B       H       H       B       B       B       H       B       H       B       B       B       H
Aradu.A01       756331  H       H       H       H       H       H       H       H       B       B       B       H       H       H       H       H       B       H       H       H       B       B       B
Aradu.A01       768081  A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A       A
Aradu.A01       783066  A       A       H       A       H       H       A       A       A       A       H       A       H       A       A       A       A       A       A       H       A       A       H
Aradu.A01       812865  H       B       H       H       H       H       H       H       H       H       H       H       H       H       H       H       B       B       H       H       B       B       H
Aradu.A01       976731  A       H       A       H       H       A       H       H       A       H       H       A       H       H       A       A       H       A       H       A       A       A       H
Aradu.A01       1089311 A       H       H       H       H       A       A       A       H       A       H       B       A       H       H       H       H       H       A       A       H       H       H
Aradu.A01       1089991 A       A       A       H       A       A       H       A       A       H       A       A       A       A       H       A       A       A       A       A       A       A       H
Aradu.A01       1113781 H       H       H       H       H       H       H       A       H       H       H       H       H       H       A       H       H       A       H       A       H       H       H
Aradu.A01       1160441 B       B       B       B       B       B       H       B       H       B       B       B       B       B       H       B       B       B       B       B       B       B       B
Aradu.A01       1638873 B       H       B       B       H       B       B       B       B       B       B       B       H       H       H       B       B       B       B       B       H       B       B
Aradu.A01       1638907 B       H       B       B       H       B       B       B       H       B       B       B       H       H       H       B       B       B       B       B       H       B       B

谁能帮我写一个 awk 代码,它只能获取包含“A”和“B”字段的行? 不考虑
1) 仅“A”和“H”、 2) 仅“B”和“H”的行。

每个都必须同时具有 A 和 B。如果 H 也与 A 和 B 一起出现,则还应考虑该行。总之,只需要包含“A”和“B”的行,如果“H”与“A”和“B”一起存在,那么还应该考虑该行:

NR>1  {for(i=3;i<=NF;i++)
        { if ( $i ~ "A" && $i ~ "B" && $1 ~ "H" ) ;
       } ## if ;
       ## for loop is done
       print ;

上面的代码返回输出文件作为输入文件。 }

答案1

您的脚本有几个问题:

  • 它测试任何字段是否匹配两个“A”“B”,同时。只要字段只有一个字符(所以你不能得到“AB”、“BAA”等),这永远不会是真的。
  • 它正在寻找, 无论是否出现H并不重要H
  • 每次循环时它都会在(第一个字段)H中寻找$1
  • 所有这些测试的结果都没有区别:if测试没有匹配的操作。print对于每条线,总能达到。

追踪 AB 出现在同一行(在不同的字段中),您可以为每个使用一个变量:

NR>1  {
    #beginning of line - no As or Bs seen yet
    A=0
    B=0
    #looping over all fields except the first two
    #break as soon as both A and B found
    for(i=3; A*B == 0 && i<=NF; i++) {
        if ( $i ~ "A" ) A=1
        if ( $i ~ "B" ) B=1
   }
    #print line if A and B were found
    if (A && B) print
}

答案2

这不是一个awk解决方案,但这grep似乎可以解决问题:

egrep '^Aradu\.[A-Z][0-9]{2}.*A.*B|^Aradu\.[A-Z][0-9]{2}.*B.*A' aradu
Aradu.A01       463100  B       B       A       A       A       A       A       H       B       A       A       H       H       H       H       H       B       A       B       A       H       H       A
Aradu.A01       1089311 A       H       H       H       H       A       A       A       H       A       H       B       A       H       H       H       H       H       A       A       H       H       H

aradu你的示例文件在哪里。

编辑,正则表达式的细分:
^Aradu\.[A-Z][0-9]{2}= 以“Aradu”开头的行,后跟文字“。”,后跟任意大写字符,后跟任意整数两次。
.*A.*B= 后跟任意字符,任意次数(.*),后跟文字“A”,后跟文字“B”
|= 逻辑或。
(直到表达式的开头相同)
.*B.*A= 任意字符,重复任意次数,后跟文字“B”,后跟文字“A”。

grep没有&&(逻辑与)运算符,这是您可以搜索的最接近的(据我所知)行A && B || B && A

相关内容