File::Find is the way if you want to look at all files in one or more directories. File::Find exports one function, find(), which takes two parameters, a hash or a code reference, and a list of directories where the search starts.

Why use File::Find

File::Find protects you from a lot of nasty things that happen on filesystems. In its standard configuration it ensures that your code reference is called once for each file encountered, even if there are more symlinks pointing to it, and it also prevents nasty loops for symlinked directories.

Why avoid File::Find

There is not much reason to avoid File::Find - you could want to avoid it if you want to read files in a single directory, without recursing, when you are explicitly sure that there can be no symlinks in that directory (for example, if the filesystem dosen't allow symlinks). Then, your code could load faster. But I'd file that under premature optimization.

Caveats

If you are starting to first use File::Find, you have to deal with some idiosyncrasies.

First of all, File::Find uses some "optimization" by default to speed up searches under certain filesystems under Unix. Unfortunately, this "optimization" fails to work under other filesystems, such as the iso9600 filesystem used for cdroms. ncw tells you below what to do about it - in fact, you should always use the code ncw proposes.

In the default configuration, the directory is changed to the recursed directory, and all returned filenames are relative to the current directory. Use $File::Find::name to get a fully specified filename.

If you don't want to recurse below a certain directory, there is the (not-so-well-documented) $File::Find::prune variable, which you can set to 1 in your code reference to stop recursing into the current directory.

Examples

By popular demand, here are some examples on how to use the module. The documentation shows off some interesting code, but it's not helpful if you're looking for something to get started.

A first example, printing the filename and the filename with the path to the file. The code was stolen from a node by nate.

use strict; use File::Find; sub eachFile { my $filename = $_; my $fullpath = $File::Find::name; #remember that File::Find changes your CWD, #so you can call open with just $_ if (-e $filename) { print "$filename exists!" . " The full name is $fullpath\n"; } } find (\&eachFile, "mydir/");

In reply to File::Find by Corion

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.