Reputation: 23275
In perl
I can loop through the files in the current directory by doing the following:
foreach $file (<*.*>) {
print "$file found\n";
# do stuff
}
How can I do the same thing but to all files in all sub-directories?
Upvotes: 0
Views: 2055
Reputation: 126722
I find File::Find::Rule
unnecessarily fussy and clumsy, especially for a simple application like this. Ultimately it is just a wrapper for the core module File::Find
, and I think the base class itself is a good choice for a straightforward application like yours
File::Find
allows you to specify a callback subroutine that will be executed for every node (file or directory) within a specified root directory
By default, that subroutine is called with the following context
$File::Find::name
is set to the full path to the node$File::Find::dir
is set to the path to the directory containing the$_
is set to the name of the node, without its path$File::Find::dir
If you want, say, to list all files beneath your current directory, then you would write this. All nodes but plain files are rejected using the -f
file test operator, works on $_
and finds the right file because the working directory has been temporarily changed
use strict;
use warnings 'all';
use File::Find 'find';
find(\&wanted, '.');
sub wanted {
return unless -f;
print $File::Find::name, "\n";
}
If you prefer, you can use an anonymous subroutine within the call to find
. This code does exactly the same thing
find(sub {
return unless -f;
print $File::Find::name, "\n";
}, '.');
Upvotes: 0
Reputation: 385506
File::Find::Rule is a great module for recursively listing files.
All files (as you asked):
use File::Find::Rule qw( );
for my $qfn (File::Find::Rule->in(".")) {
...
}
Just the files with "." in their name (as per your example):
use File::Find::Rule qw( );
for my $qfn (File::Find::Rule->name("*.*")->in(".")) {
...
}
Adding ->file
limits the results to plain files (filtering out directories).
Upvotes: 6