我正在尝试从Perl脚本中的目录树中获取一组文件。有时我可以通过glob扩展来获取它们,但是我只能用正则表达式来捕获我需要的东西。
例如,我可能希望获得所有与verify/*.finished
匹配的文件以及shell扩展。当我知道“验证”目录所在的深度(例如glob(<pattern>)
)时,使用File::Find
比使用glob("*/*/*/verify/*.finished")
找到的所有内容更快,但是当我需要依赖时,我会有点卡住正则表达式匹配。
有没有办法通过正则表达式的灵活性来提高glob
的效率?
答案 0 :(得分:6)
好吧,您可以使用glob
生成完整的文件列表,然后使用正则表达式生成grep
结果:
my @files = grep { /\.finished\z/ } glob '*/*/*/verify/*';
编辑:
如果问题是如果有一个像glob一样工作但使用正则表达式的工具,我相信答案是否定的。在完全一般的情况下,我没有看到你有任何选择,只能遍历整个目录树,我怀疑你能做得比File::Find
好得多。
答案 1 :(得分:2)
最简单的方法就是调用系统find:
open(my $fh, "-|", find => ".", -type => "d", -name => "verify") or die "Err: $!";
while(<$fh>) {
chomp;
print "$_\n" for <$_/*.finished>;
}
close $fh or warn "Err: $!";
答案 2 :(得分:1)
我不确定File::Find
幕后的内容。 (它是一个XS模块吗?)如果它正在读取每个目录的全部内容并使用perl代码单独测试每个条目,则生成本机find
命令可能会更快。 glob
的相对效率可能是由于内循环以C而不是perl运行的事实。
您可以根据您对文件或搜索条件的了解进行优化。使用您的示例,可能会将其分为两个步骤:
"verify"
*.finished
答案 3 :(得分:0)
您可以尝试这样的事情:
glob '{' . join( ',', map { join( '/', ('*') x $_ ) } (1..9) ) . '}/verify/*';
看起来不像表现那么好。另外,如果您有多个verify
目录,则会将它们全部包含在内。