【问题标题】:awk to print lines matching criteriaawk 打印符合条件的行
【发布时间】:2016-09-09 21:52:03
【问题描述】:

我正在尝试打印出$1intronic|UTR3|UTR5$2 与特定模式[^*+-]+[*+-] 匹配的所有行。我认为下面的awk 很接近,但我的current output1 的一列。我可以删除这些行,但似乎不能打印它们。输入文件是制表符分隔的。谢谢你:)。

强文本

Func.refGene    Mutation Call   Mutant Allele Frequency
1   intronic    c.[434-90G>C]+[=]   52.93
1   intronic    c.[433+79A>G]+[433+79A>G]   100
1   intronic    c.[1017+56G>A]+[1017+56G>A] 100
1   exonic  c.[1119G>A]+[=] 100
5   UTR3    c.[*68A>G]+[=]  51.46

awk

awk -F'\t' '
$1 ~ "^(intronic|UTR3|UTR5)$" {
v=$2
sub(/^[^*+-]+[*+-]/,"",v)
if(v + 0 > 10)
  print sub(/^[^*+-]+[*+-]/,"",v)
}1' file

电流输出

1
1
1
1
1

期望的输出

1   intronic    c.[434-90G>C]+[=]   52.93
1   intronic    c.[433+79A>G]+[433+79A>G]   100
1   intronic    c.[1017+56G>A]+[1017+56G>A] 100
5   UTR3    c.[*68A>G]+[=] 51.46

【问题讨论】:

  • 您似乎只说要匹配 intronic|UTR3|UTR5。您所需的输出将 exonic 显示为成功匹配。你想匹配外显子吗?
  • 我很抱歉@blackpen 这些是我想要输出的,我更正了帖子输出。谢谢你:)。
  • 脚本和输入不会产生所示的输出。同样sub 返回替换的数量,而不是处理后的字符串。
  • 我怀疑你的正则表达式 ^[^*+-]+[*+-] 没有按照你的想法做,因为你输入的每一行都会匹配那个正则表达式。如果您告诉我们您要做什么以及不匹配的行(如果缺少该行,请将该行添加到您的示例输入中),那么我们可以帮助您编写它。

标签: awk


【解决方案1】:

我假设您正在寻找类似以下的内容。如果您的匹配需要调整,请提出更正建议。我用 GNU awk 尝试了以下操作。将以下文件存储到 script.awk 中。

#!/usr/bin/gawk -f

BEGIN {
   FS="[ \t]+";
}

{
   if ($2 ~ /^(intronic|UTR3|UTR5)$/ ) {
      print "Matched Mutation Call:" $2;

      if ($3 ~ /^[^*+-]+[*+-]/) {
         print "Matched Mutant Allele :" $3;

         if ($4 > 10) {
             print "Matched Freq:" $4;
             print "Matched Record:" $0;
         }

      }

   }
   print "END OF RECORD\n";
}

你运行它:

cat data | ./script.awk

如果您有更多的搜索/编程需求,学习 perl 也无妨。

#!/usr/bin/perl -w
use strict;

while (my $line=<>) {
   print "\nBEGIN OF RECORD\n";

   chomp($line);
   my @F=split(/\s+/,$line);

   if ($F[1]=~/^(intronic|UTR3|UTR5)$/) {
      print "Matched Mutation Call:".$F[1]."\n";

      if ($F[2]=~/^[^*+-]+[*+-]/) {
         print "Matched Mutant Allele :".$F[2]."\n";

         if ($F[3] > 10) {
             print "Matched Freq:".$F[3]."\n";
             print "Matched Record:".$line."\n";
         }
      }
   }
   print "END OF RECORD\n";
}

你可以这样运行它:

cat data | ./script.pl

【讨论】:

  • 非常感谢你们的帮助和解释:)。
  • wrt awk,无需指定 FS,默认值可以正常工作,并且您不需要尾随分号。 wrt调用任一解决方案谷歌UUOC。
  • 上面的 awk 脚本不包含任何 GNU awk 特定的内容,可以用于任何实现。
【解决方案2】:

我正在尝试打印出 $1 是 intronic|UTR3|UTR5 的所有行

在您的示例输入中,没有 $1 是 intronic|UTR3|UTR5 的行。在所有行中 $1 是 1 或 5 或 "Func.refGene" 。

并且 $2 匹配某个模式 [^+-]+[+-]。

在您的示例输入中,没有 $2 与此模式匹配的行。在所有行中,$2 是“Mutation Call”、“intronic”、“exonic”或“UTR3”。

但是,在某些行中,$2 是 intronic|UTR3|UTR5,而 $3 匹配 [^*+-]+[*+-]。如果这是你想要的,你需要:

awk -F'\t' '$2 ~ "^(intronic|UTR3|UTR5)$" && $3 ~ "[^*+-]+[*+-]"' file

这会产生您想要的输出。

但是,您确定您了解[^*+-]+[*+-] 模式的含义吗?这意味着:除[*+-] 之外的任何字符中的1 个或多个,后跟[*+-]。这意味着与 [^*+-][*+-] 相同。很可能,您的意思是其他模式。

最后,您的程序几乎与您想要编写的内容无关。要么你想要完全不同的东西,要么你的程序根本没有意义。

【讨论】:

    【解决方案3】:

    Awk 字段编号(以及字符串和数组索引)从 1 开始,而不是 0:

    $ awk '($2~/^(intronic|UTR[35])$/) && ($3~/^[^*+-]+[*+-]/) && ($4>10)' file
    1   intronic    c.[434-90G>C]+[=]   52.93
    1   intronic    c.[433+79A>G]+[433+79A>G]   100
    1   intronic    c.[1017+56G>A]+[1017+56G>A] 100
    5   UTR3    c.[*68A>G]+[=]  51.46
    

    但您的示例输入中的每 $3 都包含一个 [*+-] 字符,并且在其前面有 [^*+-] 字符,因此该 regexp 是错误的,或者您的输入没有涵盖它打算从输出中排除的情况。照原样,它什么也没做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      • 2013-03-04
      • 2018-09-09
      • 2011-01-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多