spx2 has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

I am trying to use File::Find::prune so that I cut off from recursive descent certain
directories.However,when in the "wanted" function I reach the directory which I don't want to
recurse into I set File::Find::prune=1 and afterwards no subdirectories of it are used in the search.
Until here all is ok
But I don't want any of the files in that directory to be traversed.
I am seeing that altough I set prune to 1 the files in that directory(not its subdirectories,just the
directory) are still traversed.
How can I do this?

Regards,
Stefan

Replies are listed 'Best First'.
Re: File::Find::prune problems
by grinder (Bishop) on Mar 28, 2008 at 12:50 UTC

    If you're starting out with File::Find, then the best advice I can give you is... don't. It is old and bletcherous and there's no need to use it for new work.

    Much nicer is File::Find::Rule, which will cut off the depth search in a much more declarative manner, letting you get on with your job and not having to write so much make-work code to tweak File::Find to do your bidding.

    my @files = File::Find::Rule->new ->maxdepth(2) ->file() ->in('/path/to/stuff');

    • another intruder with the mooring in the heart of the Perl

      I've found File::Find::Rule also nice but the moment I started realising File::Find is obsolete
      I was already too far on the way to finishing what I had started.
      but I agree File::Find::Rule is very nice(it's actually a generalisation of what I'm doing).
Re: File::Find::prune problems
by amarquis (Curate) on Mar 28, 2008 at 12:52 UTC

    I tested with:

    find(\&wanted, "/usr/home/amarquis"); sub wanted { print $File::Find::name . "\n"; if ($File::Find::dir =~ /images/) { $File::Find::prune = 1; } }

    And indeed it continued to call wanted for files in "images" but did not go into subdirectories. But since you already have in place a check to see if you want to prune a directory, why not extend that check to before you process a file? For example:

    sub wanted { # Prune this directory so we don't recurse farther, # And return so we don't process this file. if ($File::Find::dir =~ /images/) { $File::Find::prune = 1; return; } # Now we can do our processing: print $File::Find::name . "\n"; }
      You are pruning too late. You want to prune when $File::Find::name or $_ (not $File::Find::dir) matches the directory:
      if ( -d and /images/ ) { $File::Find::prune = 1; return; } # Do your processing

        Thank you for the correction. I just tried it out, works great. For some reason I thought from the documentation that if you set prune to 1 while it was simply looking at a directory it would prune the parent directory.

        This is a really important point - prune on $File::Find::name match works best. e.g.

        my $crnt_file = $File::Find::name; my $root = $::root_dir; if (scalar grep($crnt_file =~ m/^$root$_/, @::prune) != 0) { print Dumper($crnt_file); $File::Find::prune = 1; return; }

        This tip helped heaps. Thanks.

      thank you very much amarquis,it was a very elegant way to fix the problem.
      I've tried to get into cpanforum at file::find module but they I search for it and can't find it.
      I believe this is a BUG of File::Find and I would like to notify it.
      How could I do this ?

        I'm not sure based on the wording in the documentation that it is a bug. I don't think it is a great feature but, hey, I'm not the author. You should see a link to the bug tracker for a module on its page at CPAN.org, though. (Edit: Ignore what I said here, and listen to anonymonk above)

        clinton's File::Find::Rule looks to be a pretty sweet interface, though, that fixes your issue with prune neatly. I'd check it out.

        CPAN Forum is for discussion, not for bugs. RT is for bugs.

        Since File::Find belongs to the Perl core distro, and it is not a dual-life module (i.e. it does not have another version seperately published on CPAN like for instance threads::shared), you can find its discussion forum at /dist/perl. Similarly, the bug queue is at bugs.perl.org and you report with perlbug.