使用新参数运行自己的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更好。这仍然是最后的选择,但如果我不能得到这个工作。

任何人都可以告诉我哪里出错了吗?我感觉有些变量正在继续,并且/或者脚本的第二次运行不会从我想要的位置开始。我不知道如何解决这个问题,但我已经尝试了所有我可能会遇到的故障排除,所以任何帮助都将不胜感激。

+1

这会受益于我认为的一些示例数据。 – Sobrique

+1

ow。确实使用一个子! ///请提供演示问题的数据和预期的输出 – ikegami

我想你只需要声明一个可以递归调用的子程序。

#!/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";} 
} 
+0

谢谢您的建议!看起来子程序是一个好主意。 但是我遇到的问题与以前使用此代码的情况相同:只有部分工具包输出被写入,并且它被写出来(在输出的其余部分之后而不是中间被调用的地方)。 – Zyzyx