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

Perl比较两个数组的单个元素,perl,loops,Perl,Loops,我有两个文件,每个文件有两列: FILE1 A B 1 # 2 @ 3 ! 4 % 5 % FILE 2 A B 3 # 4 ! 2 & 1 % 5 ^ Perl脚本必须比较两个文件中的A列,并且只有当它们相等时,才能打印文件2的B列 到目前为止,我有以下代码,但我得到的只是一个无限循环,其中#来自B列 use strict; use warnings; use 5.010; print "enter sit

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

FILE1

A   B

1   #

2   @

3   !

4   %

5   %

FILE 2

A   B

3   # 

4   !

2   &

1   %

5   ^
Perl脚本必须比较两个文件中的A列,并且只有当它们相等时,才能打印文件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];
                }
        }
}
使用严格;
使用警告;
使用5.010;
打印“进入站点:”。“\n”;
chomp(我的$s=);
打印“输入蛋白质:”。“\n”;
chomp(我的$p=);
打开(文件“<$s”)或死亡;
打开(OUT,“>PSP.txt”)或死亡;
打开(文件2,“<$p”)或死亡;
我的@firstcol;
我的@secondcol;
我的@thirdcol;
而()
{

接下来,如果$。我假设列A是有序的,并且您实际上想要比较文件1中的第一个条目和文件2中的第一个条目,依此类推

如果这是真的,那么您就有了不需要的嵌套循环。请将上一个while简化为:

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()
中咀嚼数据。这可能会在以后引入错误。

如果您的文件名为
file1.txt
file2.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列中,仅行
A
5

如果没有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]);
}
使用严格;
使用警告;
我的$文件;
@{$files->{${}}=map{[split/\s+/]}grep{!/^\s*$/}do{local(@ARGV)=“file$\.txt”;}用于(1..2);
对于我的$line1(@{$files->{1}){
my$line2=shift@{$files->{2};
打印$line2->[1],“\n”如果($line1->[0]eq$line2->[0]);
}

我无法检查它,因为我在手机上。希望这能给你一个想法。

我做了更改,但现在我得到了一个空白输出。for(我的$I=0;在你的
while()之后的$I)
循环,验证您的数据是否按预期设置。
使用data::Dump;dd\@secondcol2;
。最有可能的
@secondcol2
为空或其他内容,因此您可能需要在设置数据时修复某些内容。另外,
用于(my$i=0;$i若要确认循环的其余部分是否正确,请将print语句更改为与行$i匹配,如$firstcol[$i]\n”
,对于您所表示的数据,它应该与
A
5
匹配,我尝试了$i(0..$#firstcol){if($firstcol[$i]eq$firstcol2[$i]){打印“测试”;}没有模块也可以吗?@user3357980当然可以-请看编辑-但是你有什么可以重新列出模块?或者这是一个家庭作业?我就是不能把它们下载到mac上:/@user3357980-im-on-mac。如果你没有管理员权限,你可以安装
local::lib
perlbrew
。perlbrew(虽然您需要安装Xcode才能使用它)非常棒,并且可以让您不必修改系统Perl。一定要使用它!我也在想同样的事情。当心丢失的行,其中两个左值是相同的,而且散列不会按顺序生成。有人能详细说明一下吗:)当然-将密钥/值对添加到哈希中时,如果密钥已经存在,则新值将替换旧值。如果
@first
中存在重复值,则
@second
中与
@first
中的第一个重复值配对的项将消失,因为它已被第二个密钥/值对用同一把钥匙。
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;
for(keys %first)
{
    print $second{$_} if exists $second{$_}
}