Prz*_*mek 11 directory treeview recursion perl
我想以递归方式读出一个目录,以便在带有Template :: Toolkit的HTML-Page中打印数据结构.但我在如何以一种可以轻松阅读的形式保存路径和文件.
我的想法是这样开始的
sub list_dirs{
my ($rootPath) = @_;
my (@paths);
$rootPath .= '/' if($rootPath !~ /\/$/);
for my $eachFile (glob($path.'*'))
{
if(-d $eachFile)
{
push (@paths, $eachFile);
&list_dirs($eachFile);
}
else
{
push (@files, $eachFile);
}
}
return @paths;
}
Run Code Online (Sandbox Code Playgroud)
我怎么能解决这个问题?
Htb*_*baa 19
这应该可以解决问题
use strict;
use warnings;
use File::Find qw(finddepth);
my @files;
finddepth(sub {
return if($_ eq '.' || $_ eq '..');
push @files, $File::Find::name;
}, '/my/dir/to/search');
Run Code Online (Sandbox Code Playgroud)
小智 8
您应始终使用严格和警告来帮助您调试代码.例如,Perl会警告你@files没有声明.但是你的函数的真正问题是你@paths在每次递归调用时声明一个词法变量,list_dirs并且在递归步骤之后不要将返回值推回.
push @paths, list_dir($eachFile)
Run Code Online (Sandbox Code Playgroud)
如果您不想安装其他模块,以下解决方案可能对您有所帮助:
use strict;
use warnings;
use File::Find qw(find);
sub list_dirs {
my @dirs = @_;
my @files;
find({ wanted => sub { push @files, $_ } , no_chdir => 1 }, @dirs);
return @files;
}
Run Code Online (Sandbox Code Playgroud)
mdom的答案解释了你最初的尝试是如何误入歧途的.我还建议你考虑更友好的替代方案File::Find.CPAN有几种选择.这是一个.
use strict;
use warnings;
use File::Find::Rule;
my @paths = File::Find::Rule->in(@ARGV);
Run Code Online (Sandbox Code Playgroud)
另见:
这是重写您的递归解决方案.注意事项:use strict; use warnings; 并使用范围块为子例程创建静态变量.
use strict;
use warnings;
print $_, "\n" for dir_listing(@ARGV);
{
my @paths;
sub dir_listing {
my ($root) = @_;
$root .= '/' unless $root =~ /\/$/;
for my $f (glob "$root*"){
push @paths, $f;
dir_listing($f) if -d $f;
}
return @paths;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20836 次 |
| 最近记录: |