下面两个例子都可以,或者第二个是坏样式吗?
#!/usr/bin/env perl
use warnings; use strict;
my $dir = 'my_dir_with_subdir';
my ( $count, $dh );
use File::Spec::Functions;
$count = 0;
opendir $dh, $dir or die $!;
while ( defined( my $file = readdir $dh ) ) {
next if $file =~ /^\.{1,2}$/;
my $sub_dir = catdir $dir, $file;
if ( -d $sub_dir ) {
opendir my $dh, $sub_dir or die $!;
while ( defined( my $file = readdir $dh ) ) {
next if $file =~ /^\.{1,2}$/;
$count++;
}
closedir $dh or die $!;
}
else {
$count++;
}
}
closedir $dh or die $!;
print "$count\n";
use Cwd;
my $old = cwd;
$count = 0;
opendir $dh, $dir or die $!;
chdir $dir or die $!;
while ( defined( my $file = readdir $dh ) ) {
next if $file =~ /^\.{1,2}$/;
if ( -d $file ) {
opendir my $dh, $file or die $!;
chdir $file or die $!;
while ( defined( my $file = readdir $dh ) ) {
next if $file =~ /^\.{1,2}$/;
$count++;
}
closedir $dh or die $!;
chdir $dir;
}
else {
$count++;
}
}
closedir $dh or die $!;
chdir $old or die $!;
print "$count\n";
答案 0 :(得分:2)
您的问题是,您是应该更改到目前的目录还是保留在顶级目录中。
答案是: 取决于。
例如,考虑File::Find。默认行为是确实更改目录。但是,如果不希望,该模块还提供no_chdir
选项。
对于您的示例,File::Find
可能不合适,因为您不想通过所有子目录但只有一个子目录。以下是基于File::Slurp::read_dir的脚本变体。
#!/usr/bin/perl
use strict; use warnings;
use File::Slurp;
use File::Spec::Functions qw( catfile );
my ($dir) = @ARGV;
my $contents = read_dir $dir;
my $count = 0;
for my $entry ( @$contents ) {
my $path = catfile $dir, $entry;
-f $path and ++ $count and next;
-d _ and $count += () = read_dir $path;
}
print "$count\n";
答案 1 :(得分:1)
对于您的示例,最好更改为子目录,并且不要在最后更改回原始目录。那是因为每个进程都有自己的“当前目录”,所以你的perl脚本正在改变它自己的当前目录并不意味着shell的当前目录已被更改;保持不变。
如果这是一个更大的脚本的一部分,它将是不同的;我的一般偏好就是不改变目录,只是为了减少对当前目录在脚本中任何一点的混淆。
答案 2 :(得分:0)
使用File :: Find,正如您已经提出的那样:)
使用模块来解决这样的问题几乎总是比滚动自己更好,除非你真的想学习走路...... ...