Perl比较两个数组的各个元素

时间:2014-03-14 23:25:38

标签: perl loops

我有两个文件,每个文件有两列:

FILE1

A   B

1   #

2   @

3   !

4   %

5   %

FILE 2

A   B

3   # 

4   !

2   &

1   %

5   ^

Perl脚本必须比较两个文件中的A列,并且只有它们相等时才必须打印FIlE 2的B列

到目前为止,我有以下代码,但我得到的是带有#B列的无限循环

use strict;
use warnings;
use 5.010;

print "enter site:"."\n";
chomp(my $s = <>);

print "enter protein:"."\n";
chomp(my $p = <>);

open( FILE, "<  $s" ) or die;
open( OUT, "> PSP.txt" ) or die;
open( FILE2, "< $p" ) or die;

my @firstcol;
my @secondcol;
my @thirdcol;

while ( <FILE> )
{
        next if $. <2;
        chomp;
        my @cols = split;
        push @firstcol, $cols[0];
        push @secondcol, $cols[1]."\t"."\t".$cols[3]."\t"."\t"."\t"."N\/A"."\n";
}

my @firstcol2;
my @secondcol2;
my @thirdcol2;

while ( <FILE2> )
{
        next if $. <2;

        my @cols2 = split(/\t/, $_);
        push @firstcol2, $cols2[0];
        push @secondcol2, $cols2[4]."\n";
}

my $size = @firstcol;
my $size2 = @firstcol2;


for (my $i = 0; $i <= @firstcol ; $i++) {
                for (my $j = 0; $j <= @firstcol2; $j++)  {
                if ( $firstcol[$i] eq $firstcol2[$j] )
                {
                        print $secondcol2[$i];
                }
        }
}

3 个答案:

答案 0 :(得分:1)

my (@first, @second);
while(<first>){
    chomp;
    my $foo = split / /, $_;
    push @first , $foo;
}

while(<second>){
    chomp;
    my $bar = split / / , $_;
    push @second, $bar;
}

my %first = @first;
my %second = @second;

将第一个文件的哈希值设置为%first,将第二个文件构建为%second,第一列为键,第二列为值。

for(keys %first)
{
    print $second{$_} if exists $second{$_}
}

我无法检查它,因为我在移动设备上。希望能给你一个想法。

答案 1 :(得分:0)

我假设列A是有序的,并且您实际上想要将文件1中的第一个条目与文件2中的第一个条目进行比较,依此类推。

如果这是真的,那么你就拥有了你不需要的嵌套循环。简化你的最后一次:

for my $i (0..$#firstcol) {
    if ( $firstcol[$i] eq $firstcol2[$i] )
    {
        print $secondcol2[$i];
    }
}

另外,如果你完全担心文件长度不同,那么你可以调整循环:

use List::Util qw(min);

for my $i (0..min($#firstcol, $#firstcol2)) {

附加说明:您没有在第二个文件循环while ( <FILE2> )中扼杀您的数据。这可能会在以后引入一个bug。

答案 2 :(得分:0)

如果您的文件名为file1.txtfile2.txt则为下一个:

use Modern::Perl;
use Path::Class;

my $files;
@{$files->{$_}} = map { [split /\s+/] } grep { !/^\s*$/ } file("file$_.txt")->slurp for (1..2);
for my $line1 (@{$files->{1}}) {
    my $line2 = shift @{$files->{2}};
    say $line2->[1] if ($line1->[0] eq $line2->[0]);
}

打印:

B
^

在第1列中仅等于行A5

没有CPAN模块 - 产生相同的结果

use strict;
use warnings;

my $files;
@{$files->{$_}} = map { [split /\s+/] } grep { !/^\s*$/ } do { local(@ARGV)="file$_.txt";<> } for (1..2);
for my $line1 (@{$files->{1}}) {
    my $line2 = shift @{$files->{2}};
    print $line2->[1],"\n" if ($line1->[0] eq $line2->[0]);
}