【问题标题】:Perl: Search a pdf file recursivley in a large directory structurePerl:在大型目录结构中递归搜索 pdf 文件
【发布时间】:2016-11-30 23:34:03
【问题描述】:

我是 Perl 的新手。 我想在包含多个子文件夹、子子文件夹和大量文件的大型目录树中递归搜索pdf 文件。 我正在使用File::Find::Rule 来实现这一点。但是,性能影响是巨大的。 搜索脚本需要花费大量时间。

来自我的 Perl 脚本的片段:

@folders = File::Find::Rule -> file -> name('*.[pP][dD][fF]') -> in($folderPath);

有没有其他方法可以在不影响性能的情况下实现这一点?

我们将不胜感激。

【问题讨论】:

  • (非perl)命令find start_dir -name "*.[pP][dD][fF]"比较如何?这比你的 Perl 脚本快吗?

标签: perl search perl-module


【解决方案1】:

您的问题很简单:您无需查看遇到的每个候选文件,而是等待File::Find::Rule 建立一个列表并将其返回给您。这意味着您将始终等到它查看了该树下的所有文件。而且,从冷启动和足够数量的文件开始,这将需要很长时间才能显示任何结果。

相反,您可以使用底层File::Find 来检查遇到的每个文件。您可能还会发现 Path::Tiny's iterator 很有用。

您不会更改访问树下每个文件所需的时间。但是,通过处理遇到的每个文件,您将 1) 减少程序的内存占用,因为不必构建一个巨大的列表; 2) 你会更快地看到结果。

这样的事情会让你开始:

#!/usr/bin/env perl

use strict;
use warnings;

use File::HomeDir qw(my_documents);
use Path::Tiny;

my $it = path(my_documents)->iterator({ recurse => 1 });

while (my $path = $it->()) {
    return $path->is_file and $path =~ / [.] pdf \z/ix;
    do_something_with_pdf( $path );
}

sub do_something_with_pdf {
    print $_[0]->canonpath, "\n";
}

如果您喜欢File::Find::Rule规则 部分,您可能更喜欢Path::Iterator::Rule。重要的规则是避免在开始处理之前等待构建一个可能非常大的列表。

但是,如果您只需要一种快速获取所有 PDF 文件列表的方法,您应该考虑使用The Silver Searcher

【讨论】:

    【解决方案2】:

    您可以尝试改用ag

    my $cmd = 'ag -g "\.[pP][dD][fF]$" ' . $folderPath; 
    chomp(my @files = qx/$cmd/);
    

    【讨论】:

      【解决方案3】:

      尝试递归搜索子目录的子程序。在下面的示例中,您必须传递您的起始目录和一个数组(通过引用,即:\@name_of_array),该数组将填充子目录。我希望它能提高性能,但我不确定

      sub list_dirs
      {
          my ($dir, $dirs) = @_;
          opendir(D, $dir) || die "cannot open directory $dir\n\n";
          my @tmp_dirs = readdir(D);
          closedir(D);
          foreach my $tmp_dir (@tmp_dirs)
          {
              if (-d "$dir/$tmp_dir")
              {
                  next if ($tmp_dir eq "..");
                  next if ($tmp_dir eq ".");
                  push @$dirs, "$dir/$tmp_dir";
                  list_dirs("$dir/$tmp_dir", $dirs);
              }
          }
          return $dirs;
      }
      

      【讨论】:

        猜你喜欢
        • 2012-04-07
        • 2012-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-01
        • 1970-01-01
        • 2010-12-14
        相关资源
        最近更新 更多