I think it will be of more use to you to learn the workings of File::Find
, around which File::Find::Rule
is a wrapper. I still always have to read the documentation for the latter, despite having used the module dozens of times, and I think a plain File::Find
solution is often easier to read.
A few comments on your own code
You must always
use strict
as well asuse warnings
at the top of every Perl program, especially if you are asking for help with itVariables should be declared as close as possible to their first point of use. It is also better to use
and
andor
instead of&&
and||
for flow-control, so this is more appropriateopen my $filelist, '>', 'filelist.txt' or die $!;
Local variable names are conventionally written with only lower-case alphanumerics and underscore, so your subroutine would ideally be spelled
build_file
and$SubDirs
would be$sub_dirs
or$subdirs
. Capital letters are reserved for global identifiers, such package namesUsing
map
like that to print an array of strings with a newline at the end of each one is wasteful of memory. It will generate a complete new list of the strings with newline appended and pass that entire list toprint
at once. Writingprint $filelist "$_\n" for @files
is IMO much clearer, and only one line at a time is prepared and passed to
print
I can't imagine why you would want to return the value of the file handle
$filelist
, except perhaps to write more to the file after the subroutine returns. In any case you certainly don't want a reference to the file handle, and justreturn $filelist
is correct
I would write something like this
use strict;
use warnings;
use File::Find;
sub build_file {
my @dirs = @_;
open my $list_fh, '>', 'filelist.txt' or die $!;
find(sub {
return unless -f;
print $list_fh $File::Find::name, "\n" if -s _ > 500 * 1024;
}, @dirs);
return $list_fh;
}
my $fh = build_file('etc', 'dev', 'bin');
print $fh "More stuff after the list of files\n";