Как я могу перечислить все файлы в каталоге с помощью Perl?
Я обычно использую что-то вроде
my $dir="/path/to/dir";
opendir(DIR, $dir) or die "can't open $dir: $!";
my @files = readdir DIR;
closedir DIR;
или иногда я использую glob
, но в любом случае мне нужно добавить строку или две, чтобы отфильтровать .
и ..
, что очень раздражает.
Как обычно вы занимаетесь этой общей задачей?
Ответы
Ответ 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;