我是perl脚本编程的新手。我正在努力获得目录的数量&子目录。 所以我搜索了脚本编写的所有可用帮助。 但无法得到子目录的数量。以下是我使用的脚本。
use strict;
use warnings;
use File::Slurp;
my @dirs = ('.');
my $directory_count = 0;
my $file_count = 0;
my $outfile = 'log.txt';
open my $fh, '>', $outfile or die "can't create logfile; $!";
for my $dir (@dirs) {
for my $file (read_dir ($dir)) {
if ( -d "$dir/$file" ) {
$directory_count++;
}
else {
$file_count++;
}
}
print $fh "Directories: $directory_count\n";
print $fh "Files: $file_count\n";
}
close $fh;
在这里,我无法确定用/ s更改dir命令的位置。 请帮助它减少大量的手工工作。
拉维
答案 0 :(得分:2)
永远不要编写自己的目录遍历。有太多的陷阱,陷阱和边缘情况。路径分隔符,带空格的文件,备用数据流,软链接,硬链接,DFS路径......就是不要这样做。
使用File::Find
或者您更喜欢File::Find::Rule
。
我更喜欢前者,我会举一个例子:
use strict;
use warnings;
use File::Find;
my $dir_count;
my $file_count;
#find runs this for every file in it's traversal.
#$_ is 'current file'. $File::Find::Name is full path to file.
sub count_stuff {
if ( -d ) { $dir_count++ };
if ( -f ) { $file_count++ };
}
find ( \&count_stuff, "." );
print "Dirs: $dir_count\n";
print "Files: $file_count\n";
答案 1 :(得分:0)
这是一个执行它的脚本:1)没有全局变量; 2)不向命名空间添加另一个子。
#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
run(\@ARGV);
sub run {
my $argv = shift;
for my $dir ( @$argv ) {
my $ret = count_files_and_directories( $dir );
printf(
"%s: %d files and %d directories\n",
$dir,
$ret->{files},
$ret->{directories}
);
}
return;
}
sub count_files_and_directories {
my $top = shift;
my %ret = (directories => 0, files => 0);
find(
{
wanted => sub {
-d and $ret{directories} += 1;
-f and $ret{files} += 1;
},
no_chdir => 1,
},
$top,
);
\%ret;
}
答案 2 :(得分:-1)
使用File::Find::Rule
似乎更简单。例如:
use warnings;
use strict;
use File::Find::Rule;
my @files = File::Find::Rule->new->file->in('.');
my @dirs = File::Find::Rule->new->directory->in('.');