【问题标题】:Matching a value in 2 D array匹配二维数组中的值
【发布时间】:2012-08-06 16:56:36
【问题描述】:
#!/usr/bin/perl

my $file = $ARGV[0];
my $value = $ARGV[1];

my @grabbed;

open (FILE, $file);

while (<FILE>) {
    if (/alignment#  residue#/) {
            push @grabbed, $_;
            while (<FILE>) {
            last if /^$/;
            push @grabbed, $_;
            }
    }
}
close (FILE);


my $line= `awk '  {if(\$2==$value)} ' @grabbed`;

print $line;

问题:

1.首先,我不知道是否可以在数组上执行 awk? 2. 我正在尝试匹配一个存在于二维数组 (@grabbed) 的第二列中的值。 @grabbed 将如下所示:

     7         1         M     1.000         6                .VPMLG     66.63
     8         2         S     1.000        10            .QINTSARKG     66.63
     9         3         V     1.000        13         .KTAVFPRGQMSL     66.63
    10         4         L     1.000         7               .SLAKFT     66.63
    11         5         L     1.000        14        .ALSVQWIKMRYPF     66.63
    12         6         R     1.000        16      .DERSAVGTNQLYMIP     66.63
    13         7         S     1.000        18    .GDTHPKRSALFCIQVYN     66.63
    14         8         G     1.000        17     .DRFLENGAQPSTYCHM     66.63
    15         9         L     1.000        19   .NDHPELASVKRCWFGTQI     66.63
    16        10         G     1.000        18    .RLDPEGFTYAVCIKNMH     66.63

我正在尝试匹配并抓取第 2 列的值为“9”的行。

【问题讨论】:

  • 嗯...对于这些问题,大学成立了。你试过递归函数吗?

标签: perl awk matching


【解决方案1】:

当该工作也可以使用perl 完成时,无需切换到awk

for ( @grabbed ) {
    my @f = split;
    if ( $f[1] == $value ) {
        push @line, $_;
    }
}

【讨论】:

  • .......推@line,$_; } 打印@line"\n";这是创建一个永无止境的循环。你能指出我的问题吗?
  • for 循环后所有符合条件的行都将保存在@line 数组中。
【解决方案2】:

“二维数组”似乎是指一个字符串数组,每个字符串都是一个以空格分隔的值列表。

Perl 就是为这种事情而生的。您可以使用其他答案的建议来拆分每一行并查看每个值;但是,简单的正则表达式会更快。用这样的东西替换你的 awk 行:

foreach (@grabbed)
{
     #Match the beginning of the line, possibly some whitespace, 
     #then some digits, then more whitespace, then the contents of $value
     if (/^\s*\d+\s+$value/)
     {
          #The line matched: do stuff
     }
}

另外,您是否需要查看不匹配的行?如果没有,不将整个文件放入数组中会更有效;相反,只需在 while 循环中进行所有处理。

【讨论】:

  • 谢谢。稍后我有代码将使用这个数组来处理不同的东西。尽管现在面临的一个问题是,当我输入 $value = 9 时,它会抓取 9、19、90-99 的行。我如何将这个限制到 9 点?
  • 另外,由于在不同的列中匹配有类似的情况,regexp不会被“硬编码”吗?
  • 通过 if (/^\s*\d+\s+$position\s+/) 求解。如果有人可以帮助以更通用的方式浏览列,我仍然会很高兴。最好的办法是我可以传递一个参数,例如“如果 $grabbed[$column] = ....{print the line}”
  • 如果您真的想将输入视为列,请将每一行拆分为一个数组,如 Birei 的回答中所示。您还可以进一步采用这种方法并使用引用创建真正的二维数组结构:my @2d; while (&lt;FILE&gt;) { push @2d, [ split ]; } 现在您可以像这样访问特定元素:if ($2d[$row][$column] == $value) { #do stuff } 如果您要进行大量处理,这可能是要走的路在特定的列上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-24
  • 2014-11-07
  • 1970-01-01
相关资源
最近更新 更多