0

私は2つのファイルを持っています:file1.txtfile2.txt。どちらにも次の形式の行が含まれています。

file1

name1:value1

file2

name2:value2

(文字列内に)value1が見つかったかどうかを確認したいlist2name2

私はこの機能を持っています:

#!/usr/bin/perl
use warnings;
use Parallel::ForkManager;

sub loadf($);

print "Starting main program\n";
my @list1 = loadf("list1.txt");
my @list2 = loadf("list2.txt");

my $workernum = 10; 
open(OK, '>>', 'valid.txt');
open(ER, '>>', 'invalid.txt');
$pm = new Parallel::ForkManager($workernum);

my $cnt = 0;
foreach $line (@list1) {
    $cnt++;
    my $pid = $pm->start and next;
    my @data1 = split(":", $line);
    my $name1 = $data1[0];
    my $value1 = $data1[1];
    my @data2 = split(":", $list2);
    my $name2 = $data2[0];
    my $value2 = $data2[1];

    if (/$value1/i ~~ @list2) 
    {
        print OK $name1 . " - " . $value2 . "\n";
        print " [+] Found: " . $name1 . " - " . $value2 . "\n";
    }
    else
    {
        print ER $name1 . "\n";
        print " [x] Unknown: " . $name1 . " - " . $value1 . "\n";
    }
    $pm->finish;
}

close(OK);
close(ER);
print "\n*** Finished ***\n";

sub loadf($) {
    my @file;
    open(FILE, $_[0] . "\n") or die("[+] Couldn't open " . $_[0] . "\n");
    @file = <FILE>;
    close(FILE);
    return @file;
}

__END__

動作していません。私は何を間違っているのですか?

4

2 に答える 2

1

えーと...本当にあなたのアルゴリズムがわかりません、ごめんなさい。最初に、比較されたファイルからすべての行を2つの配列に読み取り、次にプロセッサループをフォークしますが、私が見るように、これらのワーカーのジョブをチャンクに分割しようとはしません(並列化するため)。

少し異なるアプローチを試すことをお勧めします。2番目のファイルのみを丸呑みしてから、最初のファイルを1行ずつ処理します。2番目のファイルの名前と値が一意であるかどうかについては言及していません。そうではないと思いますが、そうであればプログラムをさらにシンプルにすることができます。

open my $caf, '<', 'list2.txt' or die $!, "\n";
my $checkedAgainst = do { local $/;  <$caf>; };

open my $cf, '<', 'list1.txt' or die $!, "\n";

my $workernum = 10; 
$pm = new Parallel::ForkManager($workernum);

while (<$cf>) {
  my $pid = $pm->start and next;
  my ($nameToCheck, $valueToCheck) = split /:/;
  if ($checkedAgainst =~ /^\Q$valueToCheck\E:(.+)$/m) {
    print " [+] Found: $nameToCheck - $1", "\n";
  }
  else {
    print " [x] Unknown: $nameToCheck - $valueToCheck", "\n";
  }
}
$pm->finish;

つまり、最初に2番目のファイルを1つの大きな文字列にロードしてから、最初のファイルの行と(行ごとに)一致させようとします。値にどの記号が表示されるかわかりません。そのため、\ Q- \ E(quotemeta演算子)が使用されています。

更新:このコードフォークを作成しようとしましたが、私が立っている場所でテストする手段がありません。

于 2012-04-30T09:03:46.433 に答える
1
#!/usr/bin/perl

open(F,'list1.txt');
my @list1=<F>;
close(F);
open(F,'list2.txt');
my @list2=<F>;
close(F);
chomp(@list1,@list2);
foreach my $line (@list1)
{
    if ($line=~/.+\:.+/)
    {
        my @data1 = split(":", $line);
        if (my @d2=grep /$data1[1]\:/i,@list2){print " [+] Found: " . $data1[0] . " - " . [split(':',$d2[0])]->[1] . "\n";   }
        else { print " [x] Unknown: " . $data1[0] . " - " . $data1[1] . "\n"; }
    }
}
于 2012-04-30T09:12:23.080 に答える