使用Perl查找文件的效率

时间:2011-03-30 18:11:49

标签: perl find glob

我正在尝试从Perl脚本中的目录树中获取一组文件。有时我可以通过glob扩展来获取它们,但是我只能用正则表达式来捕获我需要的东西。

例如,我可能希望获得所有与verify/*.finished匹配的文件以及shell扩展。当我知道“验证”目录所在的深度(例如glob(<pattern>))时,使用File::Find比使用glob("*/*/*/verify/*.finished")找到的所有内容更快,但是当我需要依赖时,我会有点卡住正则表达式匹配。

有没有办法通过正则表达式的灵活性来提高glob的效率?

4 个答案:

答案 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运行的事实。

您可以根据您对文件或搜索条件的了解进行优化。使用您的示例,可能会将其分为两个步骤:

  1. 仅搜索目录并查找具有确切名称"verify"
  2. 的任何内容
  3. 在这些目录中查找*.finished

答案 3 :(得分:0)

您可以尝试这样的事情:

glob '{' . join( ',', map { join( '/', ('*') x $_ ) } (1..9) ) . '}/verify/*';

看起来不像表现那么好。另外,如果您有多个verify目录,则会将它们全部包含在内。