Perl grep两个数组

时间:2013-04-05 17:21:09

标签: arrays perl grep

我有一个数组填充短字符串(@pos)和第二个更大的数组(@exome)。我想在第二个数组中搜索与第一个数组中的字符串匹配。目标是打印@exome中具有匹配项的所有行

我使用perl这是我到目前为止所拥有的

#!/usr/bin/perl
use strict; use warnings;

my $pos = $ARGV[0];
my $exome = $ARGV[1];

open (F, "$pos") || die "Could not open $pos: $!\n";
my @pos = <F>;
close F;

open (F, "$exome") || die "Could not open $exome: $!\n";
my @exome = <F>;
close F;

foreach (@pos) {
    my @out = grep(/$_/, @exome);
    print @out
}

2 个答案:

答案 0 :(得分:2)

问题:

  • /$_/表示$_ =~ /$_/,所以也许您应该为模式使用不同的变量。
  • 您不会将文本转换为正则表达式模式(可以使用quotemeta完成)
  • 您可以输出两次相同的行。
  • 请不要将全局变量用于文件句柄。
  • 无需将搜索到的整个文件加载到内存中。

解决方案:

my ($pos_qfn, $exome_qfn) = @ARGV;

open(my $pos_fh, '<', $pos_qfn)
   or die("Could not open $pos_qfn: $!\n");
my @pos = <$pos_fh>;
chomp(@pos);

my $pat = join '|', map quotemeta, @pos;

open(my $exome_fh, '<', $exome_qfn)
   or die("Could not open $exome_qfn: $!\n");

while (<$exome_fh>) {
   print if /$pat/;
}

答案 1 :(得分:1)

我认为@ikegami已经给出了一个相当不错的答案,但是,他似乎在打印的数组中出错......也许@ user2249959想要@exome数组打印... 所需的核心代码不超过两行:

my $grep_pos = join '|', @pos;
my @matched_results = grep { /$grep_pos/ } @exome;

嗯,您可以立即在第二行打印出来,但阵列中的元素之间不会有空格。 两个foreach循环看起来不像Perl,只是在我看来......

P.S。我加了三点要注意 1.注意看不见的“\ n”或“\ r \ n”
2.注意每根弦的开头和结尾处的空白区域 您可以使用简单的代码解决上述两点,例如:

map { chomp; s/^\s*|\s*$// } @pos;

这将删除前面或末尾的“\ n”(如果有)和白色空格(如果你认为没有意义)。在grep之前做3。更重要!小心@pos数组文件中的空行
如果您的文件如下所示:

pos_1
pos_2
 <---- totally blank
pos_3

如果您仍然将这些行与'|'一起加入,它将变为'pos_1 | pos_2 || pos_3',这意味着@exome中的任何内容都将匹配。 (因为' || ')
chomp或s ///无济于事,你必须自己跳这一行 小心:)