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{$_}
}