我正在努力比较几个列表以找出不匹配,并认为这将是一个很好的机会来提供我过去使用的一点Perl经验。
我的代码从两个文件中分割数据,这使我可以轻松访问我需要的数据(文章编号和数量)。 然后将它们从一个文件(替换部件)与另一个文件(部件列表)进行比较。 但是,如果在替换部件列表中找到工具包(以K开头的商品编号),它将再次调用相同的Perl脚本,但使用工具包内的部件列表而不是替换部件列表。 在运行Kit的脚本之后,我希望它能继续运行它自己调用的原始脚本。
问题是在开始运行Kit的脚本之前,它将首先完全运行脚本(从我的输出中看到)。 此外,脚本的第二次运行(针对Kit)开始了一半!跳过标题和大部分数据文件的创建。
脚本接受参数:partslist.txt replacementparts.txt(或Kitparts)和可选的K作为第三个参数(如果它是Kit)。 如果脚本看起来很乱,请原谅我,我对此很新:
#!/usr/bin/perl
use strict;
use warnings;
# quit unless we have the correct number of command-line args
my $num_args = $#ARGV + 1;
if ( $num_args != 2 && $num_args != 3 ) {
print "$num_args\nUsage: perl perl.pl parts_file.txt replacements_file.txt \(optionally add \"k\" as a third parameter if a Kit\)\n";
exit;
}
# initialise files
my $file1 = $ARGV[0];
my $file2 = $ARGV[1];
open( my $fh_replacements, "<", $file2 )
or die "Could not open file '$file2' $!";
open( my $writefile_fh, ">", $writefile )
or die "Could not open file '$writefile' $!";
# initialise global variables
my $count = 1;
my @splitter;
my @splitter2;
# decide header based on whether we are dealing with a Kit
if ( lc $ARGV[2] ne "k" ) {
print {$writefile_fh} "File $file2 results:\n\n";
}
else {
print {$writefile_fh} "\tMontagekit $ARGV[1]:\n";
}
# check the data
while ( my $row = <$fh_replacements> ) {
if ( $count >= 10 && $row ne "" && $row ne "\n" )
{ #start at row 10, don't use NULL or newline rows
my $hits = 0;
open( my $fh_parts, "<", $file1 ) or die "Couldn't reopen '$file1' $!";
@splitter = split( '\s*\|\s*', $row ); #split by | with any number of spaces around it
if ( substr( $splitter[1], 0, 1 ) ne "K" ) { #check for montageKit
foreach ( @splitter ) {
my @line = <$fh_parts>;
for ( @line ) {
$_ =~ s/\x0//g; #weird windows64bit related spaces fix
if ( $_ =~ /$splitter[1]/ ) {
$hits++;
$splitter[6] =~ s/\,/\./;
@splitter2 = split( /(?<!,)\t/, $_ ); #split by tabs
}
}
}
close $fh_parts;
if ( $hits == 0 ) {
print {$writefile_fh} "$splitter[1] not matched!\n";
} #not found
elsif ( $hits == 1 ) { #found
if ( $splitter[6] == $splitter2[1] ) {
print {$writefile_fh} "$splitter[1] matched!\tQuantity match!\n";
}
else {
print {$writefile_fh} "$splitter[1] matched!\tQuantity mismatch: $splitter[6] - $splitter2[1] \(replacements - parts\)\n";
}
}
else {
print {$writefile_fh} "$splitter[1] matched $hits times!\n";
} #found multiple instances
}
else { #If kit is found, send back to separate instance of program to run for the Kit
local @ARGV = ( $ARGV[0], $splitter[1] . "\.txt", "k" );
do 'perl.pl';
}
}
$count++;
}
if ( lc $ARGV[2] ne "k" ) {
print {$writefile_fh} "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n";
}
输出:
File 2716576.txt results:
testarticle not matched!
00000126 matched! Quantity mismatch: 1.0000 - 5 (replacements - parts)
00750020 matched! Quantity match!
testarticle not matched!
testarticle not matched!
testarticle not matched!
00170018 matched 3 times!
testarticle not matched!
testarticle not matched!
testarticle not matched!
///////////////////
000222 matched! Quantity match!
00050496 matched! Quantity match!
输出中只有最后两行来自Kit文件。
我想这会比复制粘贴相同的代码更好地再次运行Kit。如果我不能让它发挥作用,那仍然是最后的选择。
谁能告诉我哪里出错了?我觉得有些变量正在结束,和/或脚本的第二次运行没有从我想要的地方开始。我不知道如何解决这个问题,我已经尝试了所有可以进行的故障排除,所以任何帮助都会非常感激。
答案 0 :(得分:1)
我认为你只需要声明一个可以递归调用的子程序。
#!/usr/bin/perl
use strict;
use warnings;
# quit unless we have the correct number of command-line args
my $num_args = $#ARGV + 1;
if ($num_args != 2 && $num_args != 3) {
print "$num_args\nUsage: perl perl.pl parts_file.txt replacements_file.txt \(optionally add \"k\" as a third parameter if a Kit\)\n";
exit;
}
process_kit (@ARGV);
sub process_kit {
my ($file1, $file2, $argv2) = @_;
open( my $fh_replacements, "<", $file2 )
or die "Could not open file '$file2' $!";
open( my $writefile_fh, ">", $writefile )
or die "Could not open file '$writefile' $!";
# initialise local variables
my $count = 1;
my @splitter;
my @splitter2;
# decide header based on whether we are dealing with a Kit
if (lc $argv2 ne "k") {
print {$writefile_fh} "File $file2 results:\n\n";}
else {
print {$writefile_fh} "\tMontagekit $ARGV[1]:\n";}
# check the data
while ( my $row = <$fh_replacements> ) {
if ( $count >= 10 && $row ne "" && $row ne "\n" ) { #start at row 10, don't use NULL or newline rows
my $hits = 0;
open( my $fh_parts, "<", $file1 ) or die "Couldn't reopen '$file1' $!";
@splitter = split( '\s*\|\s*', $row ); #split by | with any number of spaces around it
if (substr($splitter[1],0,1) ne "K") { #check for montageKit
foreach (@splitter) {
my @line = <$fh_parts>;
for (@line) {
$_ =~ s/\x0//g; #weird windows64bit related spaces fix
if ( $_ =~ /$splitter[1]/ ) {
$hits++;
$splitter[6] =~ s/\,/\./;
@splitter2 = split( /(?<!,)\t/, $_ ); #split by tabs
}
}
}
close $fh_parts;
if ( $hits == 0 ) { print {$writefile_fh} "$splitter[1] not matched!\n"; } #not found
elsif ( $hits == 1 ) { #found
if ( $splitter[6] == $splitter2[1] ) {
print {$writefile_fh} "$splitter[1] matched!\tQuantity match!\n";
}
else {
print {$writefile_fh}
"$splitter[1] matched!\tQuantity mismatch: $splitter[6] - $splitter2[1] \(replacements - parts\)\n";
}
}
else { print {$writefile_fh} "$splitter[1] matched $hits times!\n"; } #found multiple instances
}
else { #If kit is found,run again the program for the Kit
process_kit($file1, $splitter[1]."\.txt", "k");
}
}
$count++;
}
if (lc $argv ne "k") { print {$writefile_fh} "\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n";}
}