所以我知道你可以在子程序中使用opendir打开目录,然后使用readdir来读取当前工作目录中的所有文件,然后将所有文件推送到一个数组中。如果它是一个文件则遍历该数组然后打印该文件或将该文件推送到新数组中,否则如果它是一个目录,则递归地再次调用该子程序。我不明白的是,我在这里指定深度。任何帮助是极大的赞赏。
以下是我在您的帮助下找到的解决方案:
read_dir('test', 1);
sub read_dir {
$dir = shift;
$level = shift;
chdir ($dir);
opendir(DIR, '.') or die "Can't open $dir: $!";
@filesarray = readdir (DIR) or die;
closedir(DIR);
my @files;
foreach my $file (@filesarray) {
if (-f $file && $file =~ /\.txt$/i){
push @files, $file;
} ## end of if
elsif (-d $file) {
next if ($file eq ".");
next if ($file eq "..");
$dir = $file;
read_dir($dir, $level+1); ## QUESTION IS HERE?????
} ## end of elsif
} ## end of foreach
foreach my $file1 (@files) {
print "$file1\n";
}
} ## end of sub read_dir
答案 0 :(得分:0)
您可以将参数传递给名为level
的递归函数,并将函数调用为recurse(level+1, subdirectory)
。
无论如何,最好使用像File::Find
这样的专业库来完成这项任务。
答案 1 :(得分:0)
不过,这是一项很好的运动并且可以消除懒惰...
<pre><code>
#!/usr/bin/perl
use DirFind;
my $max = shift(@ARGV);
my $dir = shift(@ARGV);
my $filter = shift(@ARGV);
my %args = (
maxdepth => $max,
dirs => $dir,
filter => $filter
);
# recursive
my $df_r = DirFind->new(%args);
print join("\n", $df_r->reader_r()->result_files()),"\n\n";
exit;
package DirFind;
#
# essentially mimic find
#
#
# we'll be storing things away so we want an object
#
sub new {
my ($class, @rest) = @_;
my $self = bless({@rest}, $class);
# for the sake of all things being equal manufacture the level
# and translate to listref context so that the new() args can
# be just the simpler dirs => path
my $dir = $self->{dirs};
$self->{dirs}->[0] = join(' ', $dir, 0);
return $self;
}
#
# with tail recursion we need to store the filter and depth in new()
#
sub reader_r {
my ($self) = @_;
my ($d, $lvl) = split(' ', shift(@{$self->{dirs}}));
# no more directories
return if (!defined($d) || !defined($lvl));
return if ($lvl == $self->{maxdepth});
$lvl++;
# making the regex a bit more protected
my $filter = $self->{filter};
opendir(my $dh, $d);
my @basefiles = readdir($dh);
closedir($dh);
foreach my $f (@basefiles) {
next if ($f =~ /^\.{1,2}$/);
my $file = join('/', $d, $f);
# implicitly skip symlinks
push(@{$self->{dirs}}, join(' ', $file, $lvl)) if (-d $file);
if (-f $file) {
if (defined($filter)) {
next unless ($file =~ m!$filter!);
push(@{$self->{files}}, $file);
}
}
}
if (@{$self->{dirs}}) {
$self->reader_r();
}
# for chaining
return $self;
}
#
# the recursive form requires the additional call to get the results
# no we chain them
#
sub result_files {
my ($self) = @_;
return wantarray? @{$self->{files}}: $self->{files};
}
1;
</code></pre>