Уже ответил, но иногда удобно не заботиться о деталях реализации, и вы можете использовать некоторые модули CPAN для скрытия таких деталей.
Один из них - прекрасный модуль Path::Tiny.
Ваш код может быть:
use 5.014; #strict + feature 'say' + ...
use warnings;
use Path::Tiny;
do_search($_) for @ARGV;
sub do_search {
my $curr_node = path(shift);
for my $node ($curr_node->children) {
say "Directory : $node" if -d $node;
say "Plain File : $node" if -f $node;
}
}
Метод children
исключает .
и ..
автоматически.
Вам также необходимо понять, что тест -f
действителен только для реальных files
. Таким образом, приведенный выше код исключает, например, symlinks
(чьи точки относятся к реальным файлам) или файлы FIFO
и т. Д. Такие «файлы» можно было бы обычно открывать и читать как обычные файлы, поэтому иногда вместо -f
удобно используйте тест -e && ! -d
(например, существует, но не каталог).
У Path::Tiny
есть некоторые способы для этого, например. вы могли бы написать
for my $node ($curr_node->children) {
print "Directory : $node\n" if $node->is_dir;
print "File : $node\n" if $node->is_file;
}
метод is_file
обычно DWIM - например, делает: -e && ! -d
.
Использование Path::Tiny
вы также можете легко расширить функцию ходить все дерево с помощью метода iterator
:
use 5.014;
use warnings;
use Path::Tiny;
do_search($_) for @ARGV;
sub do_search {
#maybe you need some error-checking here for the existence of the argument or like...
my $iterator = path(shift)->iterator({recurse => 1});
while(my $node = $iterator->()) {
say "Directory : ", $node->absolute if $node->is_dir;
say "File : ", $node->absolute if $node->is_file;
}
}
Вышеприведенных печатает тип для всех файлов и каталогов рекурсивной вниз от данного аргумента ...
И так далее ... Path::Tiny действительно стоит установить.
Благодарим вас за предоставленные решения. Первая решила мою проблему :) –