How can I list all files in a directory using Perl?

匿名 (未验证) 提交于 2019-12-03 00:46:02

问题:

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; 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!