File::Copy, File::Find, File::Mkpath, etc.
################ Recursive Directory Descent with Find ###############
#!/usr/bin/perl -w
use Cwd;
use File::Find;
find(\&getpm, ".."); # 2nd thru last argument are all directories.
sub getpm
{
if (/\.pm$/)
{
$cwd = cwd();
print "$File::Find::dir/$_\n";
print "$cwd/$_\n";
}
}
######################### Find Demo Output ###########################
../perl/MainWindow.pm # From $File::Find::dir/$_
/mnt/diska/staff/jwp2286/perl/MainWindow.pm # From $cwd/$_
../perl/clean.pm
/mnt/diska/staff/jwp2286/perl/clean.pm
../perl/junk/pkg.pm
/mnt/diska/staff/jwp2286/perl/junk/pkg.pm
../perl/junk/newpkg.pm
/mnt/diska/staff/jwp2286/perl/junk/newpkg.pm
... and so on ...
########################## Critical Details ##########################
1. You are already cd'ed to the current directory when find calls your sub.
Therefore, use $_ (the current file in the current directory) in commands
called from within your sub. Use $File::Find::name in error messages so
the user knows the full path when something goes wrong.
2. Remember that find calls your sub. You cannot return any value from it
but you can do a "naked" return such as:
sub num_of_each_text_inode {
return if !-T;
$inodes{(stat)[1]}++; # Freq. of each inode!
}
3. Find does not look at . or .. in any directory except for . in the starting
directory.
4. Whenever possible, use an absolute path spec in the starting directories
given in the find call itself. Relative paths can cause problems -- come
to class to find out why! Remember that the cwd function in the Cwd
module **ALWAYS** gives an absolute path spec as its return value.
5. In your sub which find calls, declare variables as "my" variables unless
you need them in the outside world (such as the %inode hash in point 2)!!