Почему бы не использовать модуль File::Find? Он включен почти во все дистрибутивы Perl с Perl 5.x. Это не мой любимый модуль из-за грязного способа его работы, но он неплохо работает.
Вы определяете подпрограмму wanted
, которая делает то, что вы хотите, и отфильтровывайте то, что вы не хотите. В этом случае вы печатаете почти все, поэтому все wanted
делает вывод о том, что найдено.
В File::Find
имя файла хранится в $File::Find::name
, а каталог для этого файла находится в $File::Find::dir
. $_
является самим файлом и может использоваться для тестирования.
Вот основной способ, что вы хотите:
use strict;
use warnings;
use feature qw(say);
use File::Find;
my $directory = `/tmp/test`;
find (\&wanted, $directory);
sub wanted {
say $File::Find::Name;
}
Я предпочитаю, чтобы поставить свою wanted
функции в моей find
подпрограммы, так что они вместе. Это эквивалентно вышесказанному:
use strict;
use warnings;
use feature qw(say);
use File::Find;
my $directory = `/tmp/test`;
find (
sub {
say $File::Find::Name
},
$directory,
);
Хорошее программирование говорит не печатать в подпрограммах. Вместо этого вы должны использовать подпрограмму для хранения и возврата ваших данных. К сожалению, find
ничего не возвращает. Вы должны использовать глобальный массив, чтобы захватить список файлов, а затем распечатать их:
use strict;
use warnings;
use feature qw(say);
use File::Find;
my $directory = `/tmp/test`;
my @directory_list;
find (
sub {
push @directory_list, $File::Find::Name
}, $directory);
for my $file (@directory_list) {
say $file;
}
Или, если вы предпочитаете отдельную wanted
подпрограмму:
use strict;
use warnings;
use feature qw(say);
use File::Find;
my $directory = `/tmp/test`;
my @directory_list;
find (\&wanted, $directory);
sub wanted {
push @directory_list, $File::Find::Name;
}
for my $file (@directory_list) {
say $file;
}
Тот факт, что мой требуемая подпрограмма зависит от массива, который не является локальным для подпрограммы, беспокоит меня, поэтому я предпочитаю встраивать подпрограмму wanted
внутри моего вызова find
.
Одна вещь, которую вы можете сделать, - это использовать свою подпрограмму, чтобы отфильтровать то, что вы хотите. Допустим, вы заинтересованы только в JPG файлы:
use strict;
use warnings;
use feature qw(say);
use File::Find;
my $directory = `/tmp/test`;
my @directory_list;
find (\&wanted, $directory);
sub wanted {
next unless /\.jpg$/i; #Skip everything that doesn't have .jpg suffix
push @directory_list, $File::Find::Name;
}
for my $file (@directory_list) {
say $file;
}
Обратите внимание, как разыскиваемый подпрограмма делает next
на любой файл, я не хочу, прежде чем я толкаю его в мой @directory_list
массив. Опять же, я предпочитаю вложение:
find (sub {
next unless /\.jpg$/i; #Skip everything that doesn't have .jpg suffix
push @directory_list, $File::Find::Name;
}
Я знаю, что это не совсем то, что вы просили, но я просто хотел, чтобы вы знали о Find::File
модуля и познакомить вас с модулями Perl (если не уже знать о них), которые могут добавить много функциональности для Perl.
'Файл :: Spec' <- этот модуль имеет' no_upwards() 'func, чтобы скрыть все каталоги, такие как' .' или '..'. Пример: '@paths = Файл :: Spec-> no_upwards (@paths);' – gaussblurinc
Вы должны поместить 'use 5.012;' в свою программу, поскольку вы используете 'while (readdir ($ dir)) {...}' который не работает в более ранних версиях. –