我通常使用类似以下的方法:
my $dir="/path/to/dir";
opendir(DIR, $dir) or die "can't open $dir: $!";
my @files = readdir DIR;
closedir DIR;
有时我使用glob
,但无论如何,我总是需要添加一行或两行来过滤掉 .
和 ..
,这非常烦人。您通常如何处理此常见任务?
我通常使用类似以下的方法:
my $dir="/path/to/dir";
opendir(DIR, $dir) or die "can't open $dir: $!";
my @files = readdir DIR;
closedir DIR;
有时我使用glob
,但无论如何,我总是需要添加一行或两行来过滤掉 .
和 ..
,这非常烦人。您通常如何处理此常见任务?
my @files = grep {!/^\./} readdir DIR;
这也将排除所有的点文件,但这通常是您想要的。
我经常使用File::Slurp。它的好处包括:(1)如果目录不存在,它会自动停止运行。(2)默认情况下排除.
和..
。它的行为类似于readdir
,不返回完整路径。
use File::Slurp qw(read_dir);
my $dir = '/path/to/dir';
my @contents = read_dir($dir);
另一个有用的模块是File::Util,它在读取目录时提供了许多选项。例如:
use File::Util;
my $dir = '/path/to/dir';
my $fu = File::Util->new;
my @contents = $fu->list_dir( $dir, '--with-paths', '--no-fsdots' );
.
和 ..
。 - CanSpiceFile::Util
,就像编辑后的答案所示。 - FMc我通常会使用 glob
方法:
for my $file (glob "$dir/*") {
#do stuff with $file
}
这个方法在目录文件较少的情况下运行良好。但是如果目录中有大量文件,那么你需要回到readdir
并使用while
循环(将readdir
放入列表上下文与glob
一样糟糕):
open my $dh, $dir
or die "could not open $dir: $!";
while (my $file = readdir $dh) {
next if $file =~ /^[.]/;
#do stuff with $file
}
通常情况下,如果我需要读取一个目录中的一堆文件,我希望以递归方式读取它们。在这种情况下,我会使用File::Find
:
use File::Find;
find sub {
return if /^[.]/;
#do stuff with $_ or $File::Find::name
}, $dir;
[.]
很奇怪 - 为什么你更喜欢它而不是 \.
? - C. K. Young\x{2e}
),但是\.
表示它只是一个句号。由于大多数字符在字符类中没有特殊含义,因此它成为了一个很好的转义机制。 - Chas. Owensmy @files = grep !/^\.\.?$/, readdir DIR;
仅会排除.
和..
当我只想要文件(而不是目录)时,我使用带有-f
测试的grep
:
my @files = grep { -f } readdir $dir;
File::Spec->catfile($dirname, $_)
构造绝对路径名。 - Etheruse File::Slurp;
print "\nWhich folder do you want to replace text? " ;
chomp (my $input = <>);
if ($input eq "") {
print "\nNo folder entered exiting program!!!\n";
exit 0;
}
opendir(my $dh, $input) or die "\nUnable to access directory $input!!!\n";
my @dir = grep { -f "$input\\$_" } readdir $dh;