![]() |
![]()
| ![]() |
![]()
NAMEFile::Find - Traverse a directory tree. SYNOPSISuse File::Find; find(\&wanted, @directories_to_search); sub wanted { ... } use File::Find; finddepth(\&wanted, @directories_to_search); sub wanted { ... } use File::Find; find({ wanted => \&process, follow => 1 }, '.'); DESCRIPTIONThese are functions for searching through directory trees doing work on each file found similar to the Unix find(1) command. "File::Find" exports two functions, "find" and "finddepth". They work similarly but have subtle differences.
Despite the name of the finddepth() function, both find() and finddepth() perform a depth-first search of the directory hierarchy. %optionsThe first argument to find() is either a code reference to your &wanted function, or a hash reference describing the operations to be performed for each file. The code reference is described in "The wanted function" below. Here are the possible keys for the hash:
The wanted functionThe wanted() function does whatever verifications you want on each file and directory. Note that despite its name, the wanted() function is a generic callback function, and does not tell "File::Find" if a file is "wanted" or not. In fact, its return value is ignored. The "wanted" function takes no arguments but rather does its work through a collection of variables.
The above variables have all been localized and may be changed without affecting data outside of the wanted function. For example, when examining the file /some/path/foo.ext you will have: $File::Find::dir = /some/path/ $_ = foo.ext $File::Find::name = /some/path/foo.ext You are chdir()'d to $File::Find::dir when the function is called, unless "no_chdir" was specified. Note that when changing to directories is in effect, the root directory (/) is a somewhat special case inasmuch as the concatenation of $File::Find::dir, '/' and $_ is not literally equal to $File::Find::name. The table below summarizes all variants: $File::Find::name $File::Find::dir $_ default / / . no_chdir=>0 /etc / etc /etc/x /etc x no_chdir=>1 / / / /etc / /etc /etc/x /etc /etc/x When "follow" or "follow_fast" are in effect, there is also a $File::Find::fullname. The function may set $File::Find::prune to prune the tree unless "bydepth" was specified. Unless "follow" or "follow_fast" is specified, for compatibility reasons ("find.pl", find2perl) there are in addition the following globals available: $File::Find::topdir, $File::Find::topdev, $File::Find::topino, $File::Find::topmode and $File::Find::topnlink. This library is useful for the "find2perl" tool (distributed with the App::find2perl CPAN module), which when fed: find2perl / -name .nfs\* -mtime +7 \ -exec rm -f {} \; -o -fstype nfs -prune produces something like: sub wanted { /^\.nfs.*\z/s && (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_)) && int(-M _) > 7 && unlink($_) || ($nlink || (($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_))) && $dev < 0 && ($File::Find::prune = 1); } Notice the "_" in the above "int(-M _)": the "_" is a magical filehandle that caches the information from the preceding stat(), lstat(), or filetest. Here's another interesting wanted function. It will find all symbolic links that don't resolve: sub wanted { -l && !-e && print "bogus link: $File::Find::name\n"; } Note that you may mix directories and (non-directory) files in the list of directories to be searched by the wanted() function. find(\&wanted, "./foo", "./bar", "./baz/epsilon"); In the example above, no file in ./baz/ other than ./baz/epsilon will be evaluated by wanted(). See also the script "pfind" on CPAN for a nice application of this module. WARNINGSIf you run your program with the "-w" switch, or if you use the "warnings" pragma, File::Find will report warnings for several weird situations. You can disable these warnings by putting the statement no warnings 'File::Find'; in the appropriate scope. See warnings for more info about lexical warnings. BUGS AND CAVEATS
HISTORY"File::Find" used to produce incorrect results if called recursively. During the development of perl 5.8 this bug was fixed. The first fixed version of "File::Find" was 1.01. SEE ALSOfind(1), find2perl
|