поиск многих тысяч файлов в каталоге в Perl - PullRequest
1 голос
/ 07 июля 2011

Я хотел бы найти шаблон файла в шаблоне каталога в Perl, который будет возвращать многие тысячи записей, например:

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

Мне сказали, что есть разные способы справиться с этим? I.e.:

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

Какой из них был бы наиболее подходящим для запуска сценария на старых версиях Perl или минимальных установках Perl?

Ответы [ 2 ]

2 голосов
/ 07 июля 2011

Для очень больших каталогов, opendir(), вероятно, самый безопасный, так как ему не нужно читать все или выполнять какую-либо фильтрацию.Это может быть быстрее, так как порядок не важен, и в очень больших каталогах, в некоторых операционных системах, это может привести к снижению производительности.opendir также встроен во все системы.

Обратите внимание, что реальное поведение на разных платформах может отличаться.Таким образом, вы должны быть осторожны в кодировании с ним.Это в основном влияет на то, что он возвращает для таких вещей, как родительский и текущий каталог, к которым вам, возможно, придется обратиться.

glob() более полезен, когда вам нужны только некоторые файлы, соответствующие шаблону.File::Find более полезно при рекурсии через набор вложенных каталогов.Если вам это не нужно, opendir() - хорошая база.

1 голос
/ 08 июля 2011

Также у вас есть 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 см. Какие причины предпочитают использовать glob вместо readdir (или наоборот) в Perl?

Я предпочитаю использовать glob для быстрого захвата списка файлов в директории (без подкаталогов) и обработки их как

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

Это удобнее, потому что он не принимает. и ... даже если вы запрашиваете (*), а также возвращает полный путь, если вы используете dir в шаблоне glob.

Кроме того, вы можете быстро использовать glob в качестве однонаправленного канала для xargs или в цикле bash for, когда вам нужно предварительно обработать имена файлов в списке:

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

Readdir имеет преимущества в других сценариях, поэтому вам нужно использовать тот, который лучше подходит для ваших действий.

...