I'm looking for a way in Perl to list the plain files of a directory. Files only, no directories.
You want the readdir operator.
For example:
#! /usr/bin/perl
use warnings;
use strict;
my $dir = "/tmp/foo";
opendir my $dh, $dir
or die "$0: opendir: $!";
while (defined(my $name = readdir $dh)) {
next unless -f "$dir/$name";
print "$name\n";
}
Running it:
$ ls -F /tmp/foo a b c d/ $ ./prog.pl b c a
As you can see, the names come out in the order they're stored physically on the filesystem, which isn't necessarily sorted.
To go the quick-and-dirty route, you could also use the glob operator as in
print map { s!^.*/!!; "$_\n" }
grep !-d $_ =>
</tmp/foo/*>;
Note that you'll have to remove directories from the result, and the glob operator doesn't return files whose names begin with dots.
You need to use opendir, readdir and closedir functions in conjunction with -f file test operator:
opendir(my $dh, $some_dir) || die $!;
while(my $f = readdir $dh) {
next unless (-f "$some_dir/$f");
print "$some_dir/$f\n";
}
closedir $dh;
Use File::Find. It's a core module.
use File::Find;
find(\&wanted, @directories_to_search);
sub wanted
{
my $file = shift;
return unless (-f $file);
#process file
}
You can use the file test "operator" (really a function) to check for what sort of file you want.
In the simple case where you want to scan the current directory use a file glob with grep:
my @files = grep -f, <*>;
Otherwise, you can work with a directory handle:
opendir my $dh, $dirpath;
my @files = grep -f, readdir( $dh );
closedir $dh;
Another way to list all files in a directory is to use the read_dir function from the CPAN module File::Slurp:
use strict;
use warnings;
use File::Slurp qw(read_dir);
my $dir = './';
my @files = grep { -f } read_dir($dir);
It performs opendir checks for you. Keep in mind that it includes any "hidden" files (those which begin with a dot). This does not recursively list files in subdirectories of the specified directory.
File::Find::Rule from CPAN makes this utterly trivial:
use File::Find::Rule;
my @files = File::Find::Rule->file->in( $directory );
This finds all the files in the given directory or any of its subdirectories. I recommend this because of the combination of extreme flexibility and simplicity.