如何使用Perl列出目录中的所有文件?

72

Perl 中是否有列出目录中所有文件和目录的函数?我记得 Java 有 File.list() 来实现这个功能。Perl 中是否有类似的方法?

6个回答

107
如果您想获取给定目录的内容,且仅限于该目录(即没有子目录),最好的方法是使用 opendir/readdir/closedir:
opendir my $dir, "/some/path" or die "Cannot open directory: $!";
my @files = readdir $dir;
closedir $dir;

你也可以使用以下方法:

my @files = glob( $dir . '/*' );

但在我看来,这并不是很好——大多数情况下,全局模式匹配(glob)是相当复杂的(可以自动过滤结果),使用它来获取目录中的所有元素似乎是一个过于简单的任务。

另一方面,如果您需要从所有目录和子目录获取内容,则基本上有一种标准解决方案:

use File::Find;

my @content;
find( \&wanted, '/some/path');
do_something_with( @content );

exit;

sub wanted {
  push @content, $File::Find::name;
  return;
}

4
我总是忘记readdir只返回相对文件名列表,而不是整个路径! - Matthew Lock
1
感谢您不鼓励在此任务中使用通配符。使用通配符的另一个缺点是,它无法找到隐藏文件(以点开头的文件)。 - josch

15

这应该可以做到。

my $dir = "bla/bla/upload";
opendir DIR,$dir;
my @dir = readdir(DIR);
close DIR;
foreach(@dir){
    if (-f $dir . "/" . $_ ){
        print $_,"   : file\n";
    }elsif(-d $dir . "/" . $_){
        print $_,"   : folder\n";
    }else{
        print $_,"   : other\n";
    }
}

1
你应该检查 opendir 是否失败(opendir...or die "错误信息:$!")。另外,我有什么遗漏吗?Win32::GUI::DoEvents() 在这里做什么?(我在问题中没有看到任何相关的内容。) - Telemachus
这是最好的方法,我不想也不希望为应该很容易完成的事情记住正则表达式,我将使用它来创建一个类似于list($dir,"f")的函数,用于文件的“f”和目录的“d”。感谢您发布这个。 - Geomorillo

14

readdir()函数可以实现此功能。

请查看http://perldoc.perl.org/functions/readdir.html

opendir(DIR, $some_dir) || die "can't opendir $some_dir: $!";
@dots = grep { /^\./ && -f "$some_dir/$_" } readdir(DIR);
closedir DIR;

11

或者 File::Find

use File::Find;
finddepth(\&wanted, '/some/path/to/dir');
sub wanted { print };

如果存在子目录,它将会遍历子目录。


5

如果你和我一样是个懒人,你可能会喜欢使用File::Slurp模块。read_dir函数将目录内容读入数组中,去掉点号,并在需要时为返回的文件添加目录前缀以获取绝对路径。

my @paths = read_dir( '/path/to/dir', prefix => 1 ) ;

3

这将列出您指定的目录中的所有内容(包括子目录),按顺序和属性显示。我花了几天时间寻找能够做到这一点的工具,从整个讨论中选取了部分内容,并加入了自己的想法进行了组合。享受吧!

#!/usr/bin/perl --
print qq~Content-type: text/html\n\n~;
print qq~<font face="arial" size="2">~;

use File::Find;

# find( \&wanted_tom, '/home/thomas/public_html'); # if you want just one website, uncomment this, and comment out the next line
find( \&wanted_tom, '/home');
exit;

sub wanted_tom {
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat ($_);
$mode = (stat($_))[2];
$mode = substr(sprintf("%03lo", $mode), -3);

if (-d $File::Find::name) {
print "<br><b>--DIR $File::Find::name --ATTR:$mode</b><br>";
 } else {
print "$File::Find::name --ATTR:$mode<br>";
 }
  return;
}

5
每一个 Perl 程序员都曾说过这句话。 - Willem van Ketwich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接