我正在编写一个程序来逐步浏览一个目录树(是的,我知道File :: Find,但我正在编写一个替代品)。
在我的程序中,我在整个目录上执行readdir
并将其放在列表中。我需要做两件事:
.
和..
我可以通过循环执行此操作,或者我可以使用map
和grep
:
# Map and Grep
my @dir_stack = readdir $dir_fh;;
@dir_stack = grep { !/^\.{1,2}$/ } @dir_stack;
@dir_stack = reverse map { "$cwd/$_" } @dir_stack;
push @stack, @dir_stack;
# Read Loop
opendir $dir_fh, $cwd;
my @dir_stack;
foreach my $file (readdir $dir_fh) {
next if $file =~ /^\.{1,2}$/; #Skip "." and ".."
unshift @dir_stack, "$cwd/$file";
}
push @stack, @dir_stack;
如何合并grep
和map
?
opendir $dir_fh, $cwd;
my @dir_stack = readdir $dir_fh;;
@dir_stack = grep { !/^\.{1,2}$/ && {$_ = "$cwd/$_"} } @dir_stack;
push @stack, reverse @dir_stack;
我想让我的代码在下周看到可读,当我看到它并试图弄清楚发生了什么。我还需要我的代码才能有效。
答案 0 :(得分:7)
在grep中修改$_
?呸!使用anon哈希构造函数有什么用呢?
@dir_stack = grep { !/^\.{1,2}$/ && {$_ = "$cwd/$_"} } @dir_stack;
应该是
@dir_stack = map { /^\.\.?\z/ ? () : "$cwd/$_" } @dir_stack;
但我个人觉得使用map和grep比组合它们更具可读性。
push @stack,
reverse
map "$cwd/$_",
grep !/^\.\.?\z/,
readdir $dh;
对reverse
的需求相当奇怪,而且这里比隐藏unshift
更加明显,所以这是另一个奖励。
答案 1 :(得分:2)
为了使您的代码更具可读性,您只需要再添加一行:
# exclude '.' and '..', and prepend dir name to each elem in @dir_stack
: - )
答案 2 :(得分:1)
听起来你可能需要glob
。虽然我相信它会排除所有以.
开头的文件(即隐藏文件),而不仅仅是.
和..
。当然,你不能在路径上有空格。
my @stack = glob "$dir_fh/*";
它会在您提供路径时返回。