Подтвердить что ты не робот

Как я могу перечислить все файлы в каталоге с помощью Perl?

Я обычно использую что-то вроде

my $dir="/path/to/dir";
opendir(DIR, $dir) or die "can't open $dir: $!";
my @files = readdir DIR;
closedir DIR;

или иногда я использую glob, но в любом случае мне нужно добавить строку или две, чтобы отфильтровать . и .., что очень раздражает. Как обычно вы занимаетесь этой общей задачей?

4b9b3361

Ответ 1

Обычно я использую метод glob:

for my $file (glob "$dir/*") {
    #do stuff with $file
}

Это отлично работает, если в каталоге нет большого количества файлов. В таких случаях вам нужно переключиться на readdir в цикле while (помечать readdir в контексте списка так же плохо, как glob):

open my $dh, $dir
    or die "could not open $dir: $!";

while (my $file = readdir $dh) {
    next if $file =~ /^[.]/;
    #do stuff with $file
}

Часто, если я читаю кучу файлов в каталоге, я хочу прочитать их рекурсивным образом. В таких случаях я использую File::Find:

use File::Find;

find sub {
    return if /^[.]/;
    #do stuff with $_ or $File::Find::name
}, $dir;

Ответ 2

my @files = grep {!/^\./} readdir DIR;

Это также исключает все точечные файлы, но обычно это то, что вы хотите.

Ответ 3

Я часто использую File::Slurp. Преимущества включают в себя: (1) Автоматически умирает, если каталог не существует. (2) По умолчанию отключены . и ... Это поведение похоже на readdir, поскольку оно не возвращает полные пути.

use File::Slurp qw(read_dir);

my $dir = '/path/to/dir';
my @contents = read_dir($dir);

Другим полезным модулем является File::Util, который предоставляет множество опций при чтении каталога. Например:

use File::Util;
my $dir = '/path/to/dir';
my $fu = File::Util->new;
my @contents = $fu->list_dir( $dir, '--with-paths', '--no-fsdots' );

Ответ 4

Если некоторые из точечных файлов важны,

my @files = grep !/^\.\.?$/, readdir DIR;

исключает только . и ..

Ответ 5

Когда мне просто нужны файлы (в отличие от каталогов), я использую grep с тегом -f:

my @files = grep { -f } readdir $dir;

Ответ 6

Спасибо Крису и Эфиру за ваши рекомендации. Я использовал следующее, чтобы прочитать список всех файлов (исключенных каталогов) из каталога, ссылающегося на каталог, отличный от моего текущего каталога, в массив. Массив всегда пропускал один файл, когда не использовал абсолютный путь в инструкции grep

use File::Slurp; 

print "\nWhich folder do you want to replace text? " ;
chomp (my $input = <>);
if ($input eq "") {
print "\nNo folder entered exiting program!!!\n";
exit 0;
} 

opendir(my $dh, $input) or die "\nUnable to access directory $input!!!\n"; 

my @dir = grep { -f "$input\\$_" } readdir $dh;