RanRag RanRag - 2 years ago 120
Perl Question

Perl: How to stop File::Find entering directory recursively?

I was looking at Perl's

module and tried it in the following way:


use warnings;
use strict;

use File::Find;

find({wanted => \&listfiles,
no_chdir => 1}, ".");

sub listfiles{
print $File::Find::name,"\n";

Now When I run it I get the below output:

Noob@Noob:~/tmp$ perl test.pl

Now, I was thinking that by setting
I will make my code to not enter any directory if it came across one. But the output clearly shows that my code is entering
directory and listing its files.

So, how do I change my code to behave like
and not enter any directory. Also I am getting
in front of my file/directory names can that be removed?

I am using Perl 5.14.

Answer Source

$File::Find::prune can be used to avoid recursing into a directory.

use File::Find qw( find );

my $root = '.';
   wanted   => sub { listfiles($root); },
   no_chdir => 1,
}, $root);

sub listfiles {
   my ($root) = @_;
   print "$File::Find::name\n";
   $File::Find::prune = 1  # Don't recurse.
      if $File::Find::name ne $root;

You can set prune conditionally if you so desire.

use File::Basename qw( basename );
use File::Find     qw( find );

my %skip = map { $_ => 1 } qw( .git .svn ... );

   wanted   => \&listfiles,
   no_chdir => 1,
}, '.');

sub listfiles {
   if ($skip{basename($File::Find::name)}) {
      $File::Find::prune = 1;

   print "$File::Find::name\n";

no_chdir is not necessary — it has nothing to do with what you are trying to do — but I like what it does (prevents changes to the cwd), so I left it in.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download