我正在开发一个简单的循环,但它不起作用。我有两个文件,我根据一个共同的ID进行比较。它有点工作,因为它只输出第一个结果和第一个结果!因此它不会循环遍历其余文件(或最后一个文件,因为输出包含第一个文件中的所有行)。它输出第一个文件中的所有行,但它只将第二个文件的第一个结果附加到outfile中。这是我的代码澄清:
use strict;
use warnings;
my $inputfile1 = shift || die "Give input & output!\n";
my $inputfile2 = shift || die "Give input & output!\n";
my $outputfile = shift || die "Give input!\n";
open my $INFILE1, '<', $inputfile1 or die "In use / Not found :$!\n";
open my $INFILE2, '<', $inputfile2 or die "In use / Not found :$!\n";
open my $OUTFILE, '>', $outputfile or die "In use / Not found :$!\n";
while (<$INFILE1>) {
s/"//g;
my @elements = split /;/, $_;
while (<$INFILE2>) {
s/"//g;
my @loopelements = split /;/, $_;
if ($elements[11] eq $loopelements[0]){
$elements[12] = $loopelements[1];
$elements[13] = $loopelements[2];
}
}
my $output_line = join(";", @elements);
print $OUTFILE $output_line;
#print "\n"
}
close $INFILE1;
close $INFILE2;
close $OUTFILE;
exit 0;
我的第一次尝试就是这段代码,它的工作原理是部分的。为什么?:中途崩溃了。当我检查输出文件时,它工作到大约一半并停止。不明白为什么!另外,我认为下面的那个效率较低,或两者都有更好的选择?
$inputfile1=$ARGV[0];
$inputfile2=$ARGV[1];
$outputfile1=$ARGV[2];
open(INFILE1,$inputfile1) || die "Give input & output :$!\n";
open(INFILE2,$inputfile2) || die "Give input & output :$!\n";
open(OUTFILE_1,">$outputfile1") || die "Give input & output :$!\n";
$i = 0;
$j = 0;
@infile1=<INFILE1>;
@infile2=<INFILE2>;
foreach ( @infile1 )
{
@elements = split(";",$infile1[$i]);
$j=0;
foreach ( @infile2 )
{
@loopelements = split(";",$infile2[$j]);
if ($elements[11] eq $loopelements[0]){
$elements[12] = $loopelements[1];
$elements[13] = $loopelements[2];
$printen = 1;
last;
}
$j = $j+1;
}
@elements = join(";",@elements);
print "$i\r";
if ($printen == 1) { print OUTFILE_1 "@elements"; };
$i = $i+1;
}
close(INFILE1);
close(INFILE2);
close(OUTFILE_1);
有人可以指出我在顶部的代码中出错的地方吗?
答案 0 :(得分:3)
第一个文件的第一行是在外循环的第一次迭代中读取的。
在第一次迭代过程中, all 在内循环中读取第二个文件的行。
然后外循环的第一次迭代结束。
现在,外循环的第二次迭代出现了。是否还有剩余的第二个文件行可供阅读?否
将问题简化为最简单的,这两行附近有注释使得程序循环遍历第二个文件的行每次 :
use warnings;
my $inputfile1 = shift || die "Give input & output!\n";
my $inputfile2 = shift || die "Give input & output!\n";
open my $INFILE1, '<', $inputfile1 or die "In use / Not found :$!\n";
open my $INFILE2, '<', $inputfile2 or die "In use / Not found :$!\n";
my $infile2_pos = tell $INFILE2; # remember start position
while (<$INFILE1>) {
print;
seek $INFILE2, $infile2_pos, 0; # seek the start position
while (<$INFILE2>) {
print;
}
}
如果太慢,我会看到你可以做的两件事:
我的意思是:
open my $BIGFILE, '<', $bigfile or die "In use / Not found :$!\n";
open my $SMALLFILE, '<', $smallfile or die "In use / Not found :$!\n";
my @smallfile_array = <$SMALLFILE>;
while (<$BIGFILE>) {
print;
foreach (@smallfile_array) {
print;
}
}
答案 1 :(得分:0)
检查@ArjunShankar帖子是否存在代码问题。我不是在做同样的事情而是发布另一种方法。
use strict
open my $IFILE1, '< myfile.csv' or die $!;
open my $IFILE2, '< myfile.csv' or die $!;
my %File1 = map {s/"//g; (join '-',(split /,/)[0,2]),$_} <$IFILE1>;
my %File2 = map {s/"//g; (join '-',(split /,/)[0,2]),$_} <$IFILE2>;
foreach my $Key (keys %File1) {
print "REQD-DETAILS" if exists $File2{$Key};
}