使用新参数运行自己的Perl脚本
为了找到不匹配,我正在比较几个列表,并且认为这将是一个很好的机会,可以将我以前使用的Perl体验的一点点。我的代码从两个文件中拆分数据,使我能够轻松访问我需要的数据(大多数是文章数量和数量)。 然后将它们从一个文件(替换零件)与另一个零件(零件清单)进行比较。 但是,如果在替换部件列表中找到一个工具包(文章编号以K开头),它将再次调用相同的Perl脚本,但使用工具包内的部件列表而不是替换部件列表。 在运行Kit的脚本之后,我希望它能继续运行原来的脚本。使用新参数运行自己的Perl脚本
问题是在开始运行Kit的脚本之前,它将首先完全运行脚本(如从我的输出中看到的那样)。 此外,脚本的第二次运行(为Kit)开始半途!跳过标题和我的大部分数据文件的创建。
如果脚本是Kit,那么脚本需要参数:partslist.txt replacementparts.txt(或Kitparts)和一个可选的K作为第三个参数。 请原谅我,如果脚本看起来杂乱无章,我很新的这一点:
#!/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更好。这仍然是最后的选择,但如果我不能得到这个工作。
任何人都可以告诉我哪里出错了吗?我感觉有些变量正在继续,并且/或者脚本的第二次运行不会从我想要的位置开始。我不知道如何解决这个问题,但我已经尝试了所有我可能会遇到的故障排除,所以任何帮助都将不胜感激。
我想你只需要声明一个可以递归调用的子程序。
#!/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";}
}
谢谢您的建议!看起来子程序是一个好主意。 但是我遇到的问题与以前使用此代码的情况相同:只有部分工具包输出被写入,并且它被写出来(在输出的其余部分之后而不是中间被调用的地方)。 – Zyzyx
这会受益于我认为的一些示例数据。 – Sobrique
ow。确实使用一个子! ///请提供演示问题的数据和预期的输出 – ikegami