The first argument to find() is a code reference
(like a pointer to a subroutine) and the rest of the arguments
are the directories where to search. For each file in those
directories, the subroutine is called with the file name as
its argument. The subroutine is responsible for checking whatever
you want to check, and for doing whatever you want to do. So
for example, if you want to print all files ending in .tex
under your 'Docs' directory, you could do something like this:
use File::Find;
find( sub {
/\.tex$/ && print "$File::Find::name\n" },
'Docs');
Note that I used an anonymous subroutine here. The above
could have been written as follows:
find(\&wanted, 'Docs');
sub wanted {
/\.tex$/ && print "$File::Find::name\n";
}
A good way to learn is to use the find2perl program, which should
be included in your Perl distribution. It takes the same
arguments as the find command, and spits out a Perl program that
uses the File::Find module to do the same thing. By looking
at the generated programs you can learn a lot about how to
use the module.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Actually, no--the filename isn't supplied as the argument
to your subroutine. There aren't any arguments, in fact.
(Actually, if you peek at @_ in your wanted function, you
*will* see arguments. But they're not actually supplied
as arguments to your subroutine: they're the arguments to
File::Find's finddir subroutine, which calls your wanted
sub as &$wanted, which makes its @_ visible to your
subroutine.) More in perlsub.
But that's getting off track. Anyway, what File::Find
does is sets some package variables and
$_ to the file name, the directory, and a combination
of those two. From the docs:
$File::Find::dir contains the current
directory name, and $_ the current filename within
that directory. $File::Find::name contains
"$File::Find::dir/$_". You are chdir()'d to
$File::Find::dir when the function is called.
The function may set $File::Find::prune to prune
the tree.
| [reply] [Watch: Dir/Any] [d/l] |
Because this one has bitten me so many times, I will warn you
in big red letters ( oh the temptation for a little creative
html :) that Find::File, in direct contradiction of the
Principle Of Least Astonishment (POLA) and in an otherwise
stupid fashion, does a chdir on you. You will not end in
the same directory you started.
Either store your starting directory and go back after the
File::Find is done, or write your own as I have done.
Mik
Mik Firestone ( perlus bigotus maximus ) | [reply] [Watch: Dir/Any] |
Alternately, use a hashref as the first argument to find()
and set the no_chdir option.
find {wanted => \&wanted, no_chdir => 1}, '/dir';
Then, no chdir is done; and $_ will be the same as $File::Find::name.
| [reply] [Watch: Dir/Any] [d/l] |
find ({wanted => \&wanted, no_chdir=>1}, $dir1);
-OzzyOsbourne | [reply] [Watch: Dir/Any] [d/l] |
| [reply] [Watch: Dir/Any] |