用于比较数组行的perl脚本,如果行中的第一个和第三个字符串匹配

时间:2015-12-11 16:51:27

标签: perl

我有一个包含这些行的数组@array1

QA.15|foo123|P101|SR234 2345
QA.15|foo124|P102|SR236 2234
QA.15|foo125|P103|SR234 2235
QA.15|foo123|P102|SR235 2322    
QA.15|foo123|P103|SR234 2341

我使用@array1作为分隔符拆分[\\||\s+],结果@array2为:

QA.15 foo123 P101 SR234 2345 ==> Matched
QA.15 foo124 P102 SR236 2234
QA.15 foo125 P103 SR234 2235
QA.15 foo123 P102 SR235 2322
QA.15 foo123 P103 SR234 2341 ==> Matched

我需要一个输出,使得该行的第一个和第三个字符串必须与每个数组行匹配,并且必须捕获或打印出匹配的行。

预期输出

QA.15 foo123 P101 SR234 2345 
QA.15 foo123 P103 SR234 2341

下面的代码是我试图得到的结果不起作用。

my $file = "data.file";
my @array1 = `cat $file | grep -i 'P80*'`;
my @array2; 
foreach my $line (@array1)
{ 
    my @split = split /\|/, $line;
    push @array2, @split;
}
my @matched_lines;
for (my $i = 0; $i <= $#array1; $i++)
{
    foreach (@array2)
    { 
        if ($array2[1] && $array2[3] =~ m/$array1[$i++]/)
        { 
            push @matched_lines, $array1[$i];
        }
    }
 }

 print "@matched_lines\n";

1 个答案:

答案 0 :(得分:0)

关于当前计划的一些评论,首先。

  • 最初的grep greps'P80'并且上面的示例中没有(改为P10以下)
  • 分割没有空格作为分隔符
  • 在Perl中,你必须推送一个数组的引用,以创建一个数组数组
  • Algo是O(n 2

略有不同的方法:

创建一个密钥为$split[1].'|'.$split[3]的哈希(因为|不在数据中)。哈希值是@array1(行)中具有相同键的索引数组,即匹配。

最后,对于%match哈希的每个值,它是一个至少包含2个元素的数组(@ array1中的索引),打印相应的行(@ array1)。

my $file = "data.file";
my @array1 = `cat $file | grep -i 'P10'`;

my %match = ();

# make a hash of array of @array1 indexes based on [1]|[3] key
for my $i (0 .. $#array1) {
    chomp $array1[$i];
    @split = split /[\|\s]+/, $array1[$i];
    $key = $split[1] . '|' . $split[3];
    $match{$key} = [] if ( ! exists($match{$key}));
    push @{$match{$key}}, $i;
}

# go over %match and print entries with at least 2 indexes
foreach my $key ( keys %match ) {
    if ($#{$match{$key}} >= 1) {
       print "Next are matching:\n";
       for $i (0 .. $#{$match{$key}}) {
          print $array1[ ${$match{$key}}[$i] ] . "\n";
       }
    }
}