Awk:匹配字段范围并生成匹配异常

Awk:匹配字段范围并生成匹配异常,awk,string-matching,Awk,String Matching,我的文件的一个子集如下所示: row1 ./. 1/1 1/1 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 1/1 0/0 0/0 0/0 0/0 ./. 1/1 0/0 0/0 row2 ./. 0/0 0/0 0/0 0/0 0/0 0/0 0/0 ./. 0/0 0/0 0/0 ./. 0/0 0/0 0/0 0/0 0/0 ./. 0/0 ./. ./. row3 ./. 0/1 0/0 0/0 0/0 1/2 5/6 0/0 0/0 0/0 0/0

我的文件的一个子集如下所示:

row1 ./. 1/1 1/1 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 1/1 0/0 0/0 0/0 0/0 ./. 1/1 0/0 0/0
row2 ./. 0/0 0/0 0/0 0/0 0/0 0/0 0/0 ./. 0/0 0/0 0/0 ./. 0/0 0/0 0/0 0/0 0/0 ./. 0/0 ./. ./.
row3 ./. 0/1 0/0 0/0 0/0 1/2 5/6 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 ./. 1/1 0/0 0/0
row4 ./. 1/1 1/1 0/0 0/0 0/0 0/0 1/6 0/0 ./. 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 ./. 1/1 0/1 0/0
row5 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0 0/0
值的格式为n/n,其中n可以等于数字(0-9)或句点(.)

我的目标是: 如果列2、3、4、20和21相同,则返回1,否则返回0。如果忽略了包含“/”的列,则返回1,否则返回0

所需输出示例:

row1 0
row2 1
row3 0
row4 0
row5 1
第二行接收“1”,因为尽管我要比较的列中有一些“/”的实例,但感兴趣的列中的所有其他值都是相同的。第五行接收“1”,因为感兴趣的列中的所有值都相同

我写了这篇文章,它部分实现了我想要的功能(它不包括所有必要的字段组合):

我的全尺寸文件有更多的列需要包含在匹配中;有没有更简洁的方法来写这个

$ awk 'BEGIN{a[2];a[3];a[4];a[5];a[21]} {for (i in a) if ($i!="./.") b[$i]; print $1,(length(b)==1); delete b}' test.txt 
row1 0
row2 1
row3 0
row4 0
row5 1
或者,对于喜欢将代码分散在多行的人:

awk '
  BEGIN{
    a[2];a[3];a[4];a[5];a[21]
  }

  {
    for (i in a)
      if ($i!="./.")
        b[$i]
    print $1,(length(b)==1)
    delete b
  }' test.txt 
工作原理
  • 数组
    a
    确定我们检查哪些列:

    a[2];a[3];a[4];a[5];a[21]
    
    这将用于表示第2、3、4、5和21列是感兴趣的

  • 只要列值不是
    /,我们为
    a
    定义的列的每个不同值分配一个键到数组
    b

    for (i in a) if ($i!="./.") b[$i]`
    
  • 我们将结果打印出来:

    print $1,(length(b)==1)
    
    如果
    b
    的长度为1,则表示感兴趣的列(不包括
    /
    列)都具有相同的值。在这种情况下,我们打印行标题和1。如果它的长度与1不同,则打印行标题和0

  • 最后,我们删除
    b
    ,为分析下一行做准备:

    delete b
    
  • 定义感兴趣列的替代方法
    这正是我想要的。很好的解释。谢谢你,@john1024这是一个非常好的习惯用语awk。谢谢
    delete b
    
    $ awk -v x='2 3 4 5 21' 'BEGIN{split(x,a)} {for (i in a) if ($a[i]!="./.") b[$a[i]]; print $1,(length(b)==1); delete b}' test.txt 
    row1 0
    row2 1
    row3 0
    row4 0
    row5 1