可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
I will normally use the glob
method:
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
):
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
:
use File::Find; find sub { return if /^[.]/; #do stuff with $_ or $File::Find::name }, $dir;
回答2:
my @files = grep {!/^\./} readdir DIR;
This will exclude all the dotfiles as well, but that's usually What You Want.
回答3:
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.
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:
use File::Util; my $dir = '/path/to/dir'; my $fu = File::Util->new; my @contents = $fu->list_dir( $dir, '--with-paths', '--no-fsdots' );
回答4:
If some of the dotfiles are important,
my @files = grep !/^\.\.?$/, readdir DIR;
will only exclude .
and ..
回答5:
When I just want the files (as opposed to directories), I use grep
with a -f
test:
my @files = grep { -f } readdir $dir;
回答6:
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
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;