【发布时间】:2010-05-12 17:22:48
【问题描述】:
我正在寻找一种在 Perl 中列出目录的普通文件的方法。只有文件,没有目录。
【问题讨论】:
标签: perl
我正在寻找一种在 Perl 中列出目录的普通文件的方法。只有文件,没有目录。
【问题讨论】:
标签: perl
您需要将opendir、readdir和closedir函数与-f文件测试运算符结合使用:
opendir(my $dh, $some_dir) || die $!;
while(my $f = readdir $dh) {
next unless (-f "$some_dir/$f");
print "$some_dir/$f\n";
}
closedir $dh;
【讨论】:
列出目录中所有文件的另一种方法是使用 CPAN 模块 File::Slurp 中的 read_dir 函数:
use strict;
use warnings;
use File::Slurp qw(read_dir);
my $dir = './';
my @files = grep { -f } read_dir($dir);
它会为您执行 opendir 检查。请记住,它包括任何“隐藏”文件(以点开头的文件)。这不会递归地列出指定目录的子目录中的文件。
【讨论】:
使用File::Find。它是一个核心模块。
use File::Find;
find(\&wanted, @directories_to_search);
sub wanted
{
my $file = shift;
return unless (-f $file);
#process file
}
【讨论】:
您需要readdir 运算符。
例如:
#! /usr/bin/perl
use warnings;
use strict;
my $dir = "/tmp/foo";
opendir my $dh, $dir
or die "$0: opendir: $!";
while (defined(my $name = readdir $dh)) {
next unless -f "$dir/$name";
print "$name\n";
}
运行它:
$ ls -F /tmp/foo A B C D/ $ ./prog.pl b C 一个
如您所见,名称是按照它们物理存储在文件系统上的顺序出现的,不一定是排序的。
要走快速而肮脏的路线,您还可以使用 glob 运算符,如
print map { s!^.*/!!; "$_\n" }
grep !-d $_ =>
</tmp/foo/*>;
请注意,您必须从结果中删除目录,并且 glob 运算符不会返回名称以点开头的文件。
【讨论】:
来自 CPAN 的File::Find::Rule 让这一切变得微不足道:
use File::Find::Rule;
my @files = File::Find::Rule->file->in( $directory );
这将查找给定目录或其任何子目录中的所有文件。我推荐这个,因为它结合了极大的灵活性和简单性。
【讨论】: