【问题标题】:How can I list all files in a directory using Perl?如何使用 Perl 列出目录中的所有文件?
【发布时间】:2011-04-15 21:06:53
【问题描述】:

我通常使用类似的东西

my $dir="/path/to/dir";
opendir(DIR, $dir) or die "can't open $dir: $!";
my @files = readdir DIR;
closedir DIR;

或者有时我使用glob,但无论如何,我总是需要添加一两行来过滤掉...,这很烦人。 您通常如何处理这项常见任务?

【问题讨论】:

标签: perl directory


【解决方案1】:
my @files = grep {!/^\./} readdir DIR;

这也将排除所有点文件,但这通常是您想要的。

【讨论】:

    【解决方案2】:

    我经常使用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' );
    

    【讨论】:

    • ...这不是 OP 的要求。他只想过滤掉...
    • 不错。我可以让它返回完整路径(而不是基本名称)吗?
    • @David B 你也可以考虑File::Util,如编辑后的答案所示。
    【解决方案3】:

    我一般会使用glob方法:

    for my $file (glob "$dir/*") {
        #do stuff with $file
    }
    

    除非目录中有很多文件,否则这很好用。在这些情况下,您必须在while 循环中切换回readdir(将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;
    

    【讨论】:

    • [.]的用法很好奇——为什么你更喜欢\.
    • @Chris Jester-Young 我只是更喜欢它。它似乎不那么吵了(见leaning toothpick syndrome)。此外,这是合理化的,正则表达式中的转义往往意味着“下一个字符做了一些特别的事情”(例如\x{2e}),但\. 意味着它只是一个句号。由于大多数字符在字符类中没有特殊含义,因此它是一种很好的转义机制。
    【解决方案4】:

    如果某些点文件很重要,

    my @files = grep !/^\.\.?$/, readdir DIR;
    

    将仅排除 ...

    【讨论】:

    • 好吧,它可能会排除 "..\n",这在 Unix 中是合法的。并不是说我希望任何人都使用该文件名,而是人们会做一些奇怪的事情来查看是否有人会忽略他们偷偷进入您目录的文件。你可以用 \z 而不是 $ 来解决这个问题 :)
    【解决方案5】:

    当我只想要文件(而不是目录)时,我使用 grep-f 测试:

    my @files = grep { -f } readdir $dir;
    

    【讨论】:

    • 这仅在目录句柄用于当前目录时才有效。
    • @Chris:好点子,需要先 chdir,或者在 grep 中使用 File::Spec->catfile($dirname, $_) 构造一个绝对路径名。
    【解决方案6】:

    感谢 Chris 和 Ether 的建议。我使用以下内容将所有文件(排除目录)的列表从引用当前目录以外的目录的目录句柄读取到数组中。在 grep 语句中不使用绝对路径时,数组总是缺少一个文件

    use 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;
    

    【讨论】:

      猜你喜欢
      • 2023-03-28
      • 2012-12-23
      • 2011-03-13
      • 2014-03-08
      • 2011-07-11
      • 1970-01-01
      相关资源
      最近更新 更多