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

时间:2023-02-03 15:05:40

I usually use something like

我经常使用类似的东西

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

or sometimes I use glob, but anyway, I always need to add a line or two to filter out . and .. which is quite annoying. How do you usually go about this common task?

或者有时我使用glob,但无论如何,我总是需要添加一行或两行来过滤掉。而且......这很烦人。你通常怎么做这个共同的任务?

6 个解决方案

#1


7  

I will normally use the glob method:

我通常会使用glob方法:

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

This works fine unless the directory has lots of files in it. In those cases you have to switch back to readdir in a while loop (putting readdir in list context is just as bad as the glob):

除非目录中包含大量文件,否则这样可以正常工作。在这些情况下,你必须在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
}

Often though, if I am reading a bunch of files in a directory, I want to read them in a recursive manner. In those cases I use File::Find:

通常,如果我正在读取目录中的一堆文件,我想以递归方式读取它们。在这些情况下,我使用File :: Find:

use File::Find;

find sub {
    return if /^[.]/;
    #do stuff with $_ or $File::Find::name
}, $dir;

#2


13  

my @files = grep {!/^\./} readdir DIR;

This will exclude all the dotfiles as well, but that's usually What You Want.

这也将排除所有的dotfiles,但这通常是你想要的。

#3


8  

I often use File::Slurp. Benefits include: (1) Dies automatically if the directory does not exist. (2) Excludes . and .. by default. It's behavior is like readdir in that it does not return the full paths.

我经常使用File :: Slurp。好处包括:(1)如果目录不存在则自动死亡。 (2)不包括在内。和...默认情况下。它的行为就像readdir一样,它不会返回完整的路径。

use File::Slurp qw(read_dir);

my $dir = '/path/to/dir';
my @contents = read_dir($dir);

Another useful module is File::Util, which provides many options when reading a directory. For example:

另一个有用的模块是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' );

#4


7  

If some of the dotfiles are important,

如果某些dotfiles很重要,

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

will only exclude . and ..

只会排除。和..

#5


2  

When I just want the files (as opposed to directories), I use grep with a -f test:

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

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

#6


0  

Thanks Chris and Ether for your recommendations. I used the following to read a listing of all files (excluded directories), from a directory handle referencing a directory other than my current directory, into an array. The array was always missing one file when not using the absolute path in the grep statement

感谢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;

#1


7  

I will normally use the glob method:

我通常会使用glob方法:

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

This works fine unless the directory has lots of files in it. In those cases you have to switch back to readdir in a while loop (putting readdir in list context is just as bad as the glob):

除非目录中包含大量文件,否则这样可以正常工作。在这些情况下,你必须在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
}

Often though, if I am reading a bunch of files in a directory, I want to read them in a recursive manner. In those cases I use File::Find:

通常,如果我正在读取目录中的一堆文件,我想以递归方式读取它们。在这些情况下,我使用File :: Find:

use File::Find;

find sub {
    return if /^[.]/;
    #do stuff with $_ or $File::Find::name
}, $dir;

#2


13  

my @files = grep {!/^\./} readdir DIR;

This will exclude all the dotfiles as well, but that's usually What You Want.

这也将排除所有的dotfiles,但这通常是你想要的。

#3


8  

I often use File::Slurp. Benefits include: (1) Dies automatically if the directory does not exist. (2) Excludes . and .. by default. It's behavior is like readdir in that it does not return the full paths.

我经常使用File :: Slurp。好处包括:(1)如果目录不存在则自动死亡。 (2)不包括在内。和...默认情况下。它的行为就像readdir一样,它不会返回完整的路径。

use File::Slurp qw(read_dir);

my $dir = '/path/to/dir';
my @contents = read_dir($dir);

Another useful module is File::Util, which provides many options when reading a directory. For example:

另一个有用的模块是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' );

#4


7  

If some of the dotfiles are important,

如果某些dotfiles很重要,

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

will only exclude . and ..

只会排除。和..

#5


2  

When I just want the files (as opposed to directories), I use grep with a -f test:

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

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

#6


0  

Thanks Chris and Ether for your recommendations. I used the following to read a listing of all files (excluded directories), from a directory handle referencing a directory other than my current directory, into an array. The array was always missing one file when not using the absolute path in the grep statement

感谢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;