Perl脚本使用新参数运行自身

时间:2017-03-07 12:02:37

标签: perl

我正在努力比较几个列表以找出不匹配,并认为这将是一个很好的机会来提供我过去使用的一点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。如果我不能让它发挥作用,那仍然是最后的选择。

谁能告诉我哪里出错了?我觉得有些变量正在结束,和/或脚本的第二次运行没有从我想要的地方开始。我不知道如何解决这个问题,我已经尝试了所有可以进行的故障排除,所以任何帮助都会非常感激。

1 个答案:

答案 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";}
}