在Perl中找到目录模式中的数千个文件

时间:2011-07-07 16:44:13

标签: perl unix scripting find

我想在Perl中的目录模式上找到一个文件模式,它将返回数千个条目,如下所示:

find ~/mydir/*/??/???/???? -name "\*.$refinfilebase.search" -print

我被告知有不同的方法来处理它?即:

File::Find
glob()
opendir, readdir, grep
Diamond operator, e.g.: my @files = <$refinfilebase.search>

哪个最适合能够在旧版本的Perl上运行脚本或最小的Perl安装?

2 个答案:

答案 0 :(得分:2)

对于非常大的目录,opendir()可能是最安全的,因为它不需要读取所有内容或对其进行任何过滤。这可能更快,因为排序并不重要,并且在非常大的目录上,在某些操作系统上,这可能会影响性能。 opendir也内置了所有系统。

请注意,它在不同平台上的实际行为方式可能有所不同。所以你需要小心编码。这主要影响它返回的内容,如父目录和当前目录,您可能需要特别处理。

当您只想要一些按模式匹配的文件时,

glob()会更有用。通过一组嵌套目录递归时,File::Find更有用。如果您不需要,opendir()是一个很好的基础。

答案 1 :(得分:1)

你也有DirHandle

DIRHANDLE:

use DirHandle;
$d = new DirHandle ".";
if (defined $d) {
    while (defined($_ = $d->read)) { something($_); }
    $d->rewind;
    while (defined($_ = $d->read)) { something_else($_); }
    undef $d;
}

对于readdir和glob的用例,请参阅 What reasons are there to prefer glob over readdir (or vice-versa) in Perl?

我更喜欢使用glob快速获取目录中的文件列表(无子目录)并像处理

一样处理它们

map {process_bam($ _)} glob(bam_files / * .bam)

这样更方便,因为它不需要。并且..如果你在glob模式中使用dir,你甚至要求(*)并返回完整路径。

当你需要预处理列表的文件名时,你可以快速使用glob作为oneliner管道传输到xargs或bash for循环:

perl -lE 'print join("\n", map {s/srf\/(.+).srf/$1/;$_} glob("srf/198*.srf"))' | xargs -n 1.....

Readdir在其他情况下有冒险,因此您需要使用更适合您行为的那个。