Updated: October 6th, 2009
No matter what programming language you use, there comes a time when you need to search for a file somewhere on the file system. Here, I want to talk about accomplishing this task in Perl. There are many ways of doing so, most of them boring, but I want to discuss the fun and elegant way – using File::Find::Rule.
Let me briefly discuss some of the other methods first.
Limited
Using glob() (or <>, TODO verify) you can find files in a single directory, using only the limited shell wildcard support. For example,
1 | my @files = glob("tmp*"); |
Boring
File::Find is the de facto standard for searching in Perl.
This method finds files that end in .pl in "." and "../SomeDir", following symlinks:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #!/usr/bin/perl -w use File::Find; use Data::Dumper; use File::Basename; my @directories_to_search = (".", "../SomeDir"); my @file_list = (); find( { wanted => sub { if ( basename($File::Find::name) =~ /\.pl$/i ) { push @file_list, $File::Find::name; } }, follow => 1 }, @directories_to_search ); print Dumper @file_list; |
It works fine, except it's horribly ugly and boring. Let's have a look at something more fun.
The Fun And Elegant Way
File::Find::Rule. Just have a look at this beauty.
Just like above, find all .pl files in "." and "../SomeDir", following symlinks:
1 2 | print Dumper (File::Find::Rule->name("*.pl")->file->extras({ follow => 1 })-> in(".", "../SomeDir")); |
Same as above, except bypass .svn directories (shaves off a ton of time with a lot of directories):
1 2 | print Dumper (File::Find::Rule->not(File::Find::Rule->directory->name('.svn')-> prune->discard)->name("*.pl")->file->extras({ follow => 1 })->in(".", "../SomeDir")); |
Find all .log files that are older than 24 hours in "."
1 2 3 | my $epoch_time_1_day_ago = time() - 60*60*24; print Dumper (File::Find::Rule->file->name("*.log")-> mtime("<$epoch_time_1_day_ago")->in('.')); |
Be sure to read the File::Find::Rule perldoc for more options and remember: have fun with your code!
Thanks to Perlbuzz and Andy Lester for pointing me to this library a few months ago.
In the meantime, if you found this article useful, feel free to buy me a cup of coffee below.