This module makes recursive file traversal as easy as you could imagine. The following is a naked template for working with this module:use File::Find;
First, a starting directory is initialized in $dir. If you imagine the directory structure as a tree, this is the root, from which the search starts.use File::Find; my $dir = # whatever you want the starting directory to be find(\&do_something_with_file, $dir); sub do_something_with_file { #..... }
Here, the subroutine print_name_if_dir is given as an argument to find. It simply prints the name of the file if it's a directory. Note the peculiar notation... It's customary in Perl not to mention $_, so:use File::Find; find(\&print_name_if_dir, "."); sub print_name_if_dir { print if -d; }
Is equivalent to:print if -d;
Both are quite cryptic (but hey, it's Perl), and for clarity the routine could be rewritten as:print $_ if -d $_;
Routines in Perl can be anonymous, which is more suitable for such simple tasks, so the whole program may be rewritten as:sub print_name_if_dir { my $file = $_; print $file if -d $file; }
Just 3 lines of code, and we're already doing something useful !use File::Find; my $dir = # whatever you want the starting directory to be find(sub {print if -d}, $dir);
Try running it and compare the results to the previous version. You will notice that it prints the full path to the directory. What happens is the following - Find::File chdirs into each directory it finds in its search, and $_ gets only the short name (w/o path) of the file, while Find::File::name gets the full path. If, for some reason, you don't want it to chdir, you may specify no_chdir as a parameter. Parameters to find are passed as a hash reference:use File::Find; find(sub {print $File::Find::name if -d}, ".");
Note that "wanted" is the key for the file processing routine in this hash.use File::Find; find({wanted => sub {print $File::Find::name if -d} no_chdir => 1}, ".");
What goes on here ? find traverses the given directory recursively, taking notice of each file's size in the $size hash table (-s if -f means = get the size if this is a file). Then, it sorts the hash table by size, and prints the 20 largest files. That's it... I use this utility quite a lot to clean space, I hope you find it useful too (and also understand exactly how it works !)#!/usr/local/bin/perl -w ($#ARGV == 0) or die "Usage: $0 [directory]\n"; use File::Find; find(sub {$size{$File::Find::name} = -s if -f;}, @ARGV); @sorted = sort {$size{$b} <=> $size{$a}} keys %size; splice @sorted, 20 if @sorted > 20; foreach (@sorted) { printf "%10d %s\n", $size{$_}, $_; }
With this in mind, though, you must be careful when working with Windows' paths, because slashes there have a different direction. There is a nice tutorial - Paths in Perl, that explains this.
Edit by tye to add READMORE
In reply to Beginners guide to File::Find by spurperl
For: | Use: | ||
& | & | ||
< | < | ||
> | > | ||
[ | [ | ||
] | ] |