Perl:在大型目录结构中搜索pdf文件recursivley

时间:2016-11-30 09:00:14

标签: perl search perl-module

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

来自我的Perl脚本的片段:

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

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

任何帮助都将受到高度赞赏。

3 个答案:

答案 0 :(得分:2)

您的问题很简单:您正在等待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

答案 1 :(得分:1)

您可以尝试使用ag代替:

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

答案 2 :(得分:0)

尝试递归搜索子目录的子例程。在下面的示例中,您必须传递您的起始目录和一个数组(通过引用,即:\ @ 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;
}