パールソリューション。スクリプトよりもはるかに高速である必要があります。
- 各 .def ファイルから正規表現を作成します。各 .def ファイルを複数回読み取ることはありません。
opendir
ディレクトリの内容を読み取るために使用します。globを実行するよりもはるかに高速です*
が、ペナルティとして、ファイルはソートされません。あなたと私のスクリプトの出力を比較するには、使用する必要があります
diff <(sort $def.out) <(sort $def-new.out)
opendir
を aに置き換えると、glob
まったく同じ出力が得られます。スクリプトの速度は遅くなりますが、それでも古いスクリプトよりもはるかに高速です。
スクリプトは次のとおりです。
#!/usr/bin/perl
use warnings;
use strict;
my $dir = 'd'; # Enter your dir here.
my @regexen;
my @defs = glob '*.def';
for my $def (@defs) {
open my $DEF, '<', $def or die "$def: $!";
open my $TOUCH, '>', "$def-new.out" or die "$def-new.out: $!";
my $regex = q();
while (<$DEF>) {
chomp;
$regex .= "$_|"
}
substr $regex, -1, 1, q();
push @regexen, qr/$regex/;
}
# If you want the same order, uncomment the following 2 lines and comment the next 2 ones.
#
# for my $file (glob "$dir/*") {
# $file =~ s%.*/%%;
opendir my $DIR, $dir or die "$dir: $!";
while (my $file = readdir $DIR) {
next unless -f "$dir/$file";
my %matching_files;
open my $FH, '<', "$dir/$file" or die "$dir/$file: $!";
while (my $line = <$FH>) {
last if $. > 4;
my @matches = map $line =~ /$_/ ? 1 : 0, @regexen;
$matching_files{$_}++ for grep $matches[$_], 0 .. $#defs;
}
for my $i (keys %matching_files) {
open my $OUT, '>>', "$defs[$i]-new.out" or die "$defs[$i]-new.out: $!";
open my $IN, '<', "$dir/$file" or die "$dir/$file: $!";
print $OUT $_ while <$IN>;
close $OUT;
}
}
更新しました
ファイルを数回フェッチできるようになりました。1 つの巨大な正規表現を作成する代わりに、正規表現の配列が作成され、1 つずつ照合されます。