Perl 解决方案。它应该比你的脚本快得多,因为
- 它从每个 .def 文件创建一个正则表达式。它不会多次读取每个 .def 文件。
它用于opendir
读取目录内容。它比做 glob 快得多*
,但作为惩罚,文件没有排序。要比较您和我的脚本的输出,您必须使用
diff <(sort $def.out) <(sort $def-new.out)
您可以将 替换为opendir
aglob
以获得完全相同的输出。它减慢了脚本,但它仍然比旧脚本快得多。
脚本在这里:
#!/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;
}
}
更新
现在可以多次获取文件。不是创建一个巨大的正则表达式,而是创建一个正则表达式数组,并将它们逐个匹配。