perl脚本来计算Windows目录树中的文件

时间:2014-12-01 07:26:11

标签: perl

我是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命令的位置。 请帮助它减少大量的手工工作。

拉​​维

3 个答案:

答案 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('.');