Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Find a file in a list of directories

by grinder (Bishop)
on Apr 25, 2002 at 12:11 UTC ( #161924=snippet: print w/replies, xml ) Need Help??
Description: This snippet searches a series of directories for a file. For instance, you may want to open the file 'foo.txt', but it could be in any one of a number of directories, so you want to search them one after the other until you find it.

An analogy would be the way a shell finds a program based on the value of the PATH environment variable.

asdfgroup's remarks noted.

    my $target = 'foo.txt';
    my $file = do {
        my $target = undef;
        foreach my $dir( qw{ /tmp /var/tmp /foo /bar } ) {
            my $t = "$dir/$target";
            # nb: you might want to use -e here
            # but -f might be what you *really* want, YMMV
            if( -f $t ) {
                $target = $t;

    if( $target ) {
        open IN, $target or die "Cannot open $target for input: $\n";
        # ...
    else {
        die "Can't find $target.\n";
Replies are listed 'Best First'.
Re: Find a file in a list of directories
by asdfgroup (Beadle) on Apr 25, 2002 at 15:27 UTC
    more compact version of your code. And you should use '-e' test instead of '-t'
    #!/usr/bin/perl sub FileFinder { my ($target, @dir) = @_; return (grep {-e $_} map {"$_/$target"} @dir)[0]; } open(F, FileFinder('', qw(some/ dirs/ ./)) || die "File n +ot found") or die $!;
      IMO in general grep and map shouldn't be chained together, map can do greps job without having retraverse the array.
      return (map{-e "$_/$target" ? "$_/$target" : ()} @dir)[0];
      And frankly why bother with map and grep at all? This is much more efficient.
      sub FileFinder { my $target=shift; -e "$_/$target" && return "$_/$target" foreach @_; undef }
      Oh and before the premature optimization police arrest me, remember that we are searching a filesystem (possible remote etc) here. That call to -e could take a while and if we have to do more of them than we really need to then we could end up wasting a lot of time.

      Adjust the file test to your taste ;-)

      Yves / DeMerphq
      Writing a good benchmark isnt as easy as it might look.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: snippet [id://161924]
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2023-11-29 16:10 GMT
Find Nodes?
    Voting Booth?

    No recent polls found