任何时候你想写一个目录遍历器,总是使用标准的File::Find模块。在处理文件系统时,您必须能够处理奇怪的极端情况,而幼稚的实现很少这样做。
提供给回调的环境(在文档中命名wanted
)具有三个变量,它们对您想要做的事情特别有用。
$File::Find::dir
是当前目录名
$_
是该目录中的当前文件名
$File::Find::name
是文件的完整路径名
当我们找到一个不是.
or的目录时..
,我们记录完整的路径并删除它的父目录,我们现在知道它不能是叶子目录。最后,任何剩余的记录路径都必须留下,因为find
在 File::Find 中执行深度优先搜索。
#! /usr/bin/env perl
use strict;
use warnings;
use File::Find;
@ARGV = (".") unless @ARGV;
my %dirs;
sub wanted {
return unless -d && !/^\.\.?\z/;
++$dirs{$File::Find::name};
delete $dirs{$File::Find::dir};
}
find \&wanted, @ARGV;
print "$_\n" for sort keys %dirs;
您可以针对当前目录的子目录运行它
$ 叶目录时间
时间/aa/bb/某事
时间/aa/bc/任何东西
时间/aa/bc/一切
时间/ab/cc/这里
时间/ab/cc/那里
时间/ab/cd/无处不在
或使用完整路径
$叶目录/tmp/时间
/tmp/时间/aa/bb/某事
/tmp/时间/aa/bc/任何东西
/tmp/时间/aa/bc/一切
/tmp/时间/ab/cc/这里
/tmp/time/ab/cc/那里
/tmp/time/ab/cd/无处不在
或在同一调用中探测多个目录。
$ mkdir -p /tmp/foo/bar/baz/quux
$ 叶目录 /tmp/time /tmp/foo
/tmp/foo/bar/baz/quux
/tmp/时间/aa/bb/某事
/tmp/时间/aa/bc/任何东西
/tmp/时间/aa/bc/一切
/tmp/时间/ab/cc/这里
/tmp/time/ab/cc/那里
/tmp/time/ab/cd/无处不在