Файл File :: Find :: Rule реализует -X файловые тесты в качестве методов. Тот, который проверяет, является ли запись символической ссылкой (-l
), называется symlink
.
В моем прочтении вопроса вы не знаете название этого каталога (иначе зачем «находить» в нем файл?), За исключением того, что это символическая ссылка. Затем вам нужно сначала найти каталоги, которые являются символическими ссылками, а затем найти файлы в них. Для выполнения этой второй задачи вам необходимо указать модулю перейти по ссылкам.
Я использую тестовую структуру на диске
test_find/a/c/c.txt
test_find/a/b/b.txt
test_find/is_link -> a/c ("is_link" is a symbolic link to "a/c")
и из каталога прямо над ним я запускаю программу
use warnings;
use strict;
use feature 'say';
use File::Find::Rule;
my $top_dir = shift @ARGV || './test_find';
my @symlink_dirs = File::Find::Rule->directory->symlink->in($top_dir);
foreach my $dir (@symlink_dirs) {
my @files = File::Find::Rule->file->extras({follow => 1})->in($dir);
say "in $dir: @files";
}
который печатает
in test_find/is_link: test_find/is_link/c.txt
Обратите внимание, что программа найдет все файлы в всех каталогах, которые являются символическими ссылками. Написание явного цикла, как указано выше, позволяет добавить код, чтобы решить, какие из каталогов symlink действительно искать. Если вы не возражаете, просматривая их все, вы можете просто сделать
my @files = File::Find::Rule->file->extras({follow => 1})->in(@symlink_dirs);
Информацию о возможностях ограничения поиска с использованием того, что вы знаете о каталоге / файле, смотрите в документации.
Если каталог ссылок находится в иерархии, не включающей цель, просто выполните поиск в этой иерархии.
С тестовой структурой
other_hier/is_link -> ../test_find/a/c
test_find/a/c/c.txt
вам нужно только сказать ему, чтобы перейти по ссылкам
my @all_files = File::Find::Rule # may use linebreaks and spaces
-> file
-> extras({ follow => 1 })
-> in('other_hier');
При добавлении к вышеуказанной программе и распечатке это добавляет
another/is_link/c.txt
Конечно, вы можете заменить литерал 'other_hier'
на $top_dir
и вызвать программу с аргументом other_hier
(и сделать этот каталог other_hier
и ссылку в нем).
Если и ссылка, и цель находятся в одной и той же иерархии, в которой выполняется поиск, вы не сможете этого сделать; при поиске встречаются циклические ссылки (модуль обнаруживает это и завершает работу с ошибкой).