已经回答,但有时不用关心实现细节也很方便,您可以使用一些 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 真的值得安装。