2017-03-07 19 views
1

私は不一致を見つけるためにいくつかのリストを比較することに取り組んでいます。これは過去に私が使ってきた少しのPerl体験を使うよい機会になると考えました。新しいパラメータでPerlスクリプトを実行しています

私のコードは2つのファイルのデータを分割して、必要なデータに簡単にアクセスできるようにしています(記事番号と数量がほとんどです)。 次に、これらのファイルを1つのファイル(交換部品)から別のファイル(部品リスト)と比較します。 しかし、交換部品リスト(Kで始まる記事番号)にキットが見つかった場合は、同じパーツスクリプトを再度呼び出しますが、交換部品リストではなくキット内の部品リストを使用します。 キットのスクリプトを実行した後、元のスクリプトを呼び出した場所から引き続き実行したいと考えました。

問題は、(私の出力から見て)スクリプトを完全に実行してから、そのスクリプトを実行する前に実行することです。 さらに、スクリプトの2回目の実行(キット用)が途中から開始されます。ヘッダーと私のデータファイルの大部分の作成をスキップします。

スクリプトは引数:partlist.txt replacementparts.txt(またはKitparts)とオプションのKを第3引数として使用します(キットの場合)。スクリプトが乱雑に見える場合 私を許しなさい、私はこれに非常に新しいです:

#!/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! 

のみ最後の2行は、キットのファイルからです。

これは、同じコードをコピーして貼り付けて、キットを再度実行するよりも優れていると思いました。私はこれを動作させることができない場合、それはまだ最後の手段の選択肢です。

どこに間違っているのか教えていただけますか?私は、いくつかの変数が持ち越されているように感じたり、スクリプトの2回目の実行が私が好きなところから始まったりしないと感じます。私はそれを修正する方法はわかりません、私はすべてのトラブルシューティングを試してみましたので、どんな助けでも大歓迎です。

+1

これは、私が考えるいくつかのデータ例の恩恵を受けるでしょう。 – Sobrique

+1

ow。実際には代わりにサブを使用してください! ///問題を示すデータと期待する出力を提供してください – ikegami

答えて

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

ありがとうございました!サブルーチンは素晴らしい考えです。 しかし、私はこのコードを使用する前と同じ問題を抱えています:キットの出力の一部のみが書き込まれ、その場で書き出されます。 – Zyzyx

関連する問題