user1440061
user1440061

Reputation: 445

Perl search for specific subdirectory then process

So for the program I am writing, what I would like for it to do is search through all of the subdirectories within a directory. If the subdirectory name contains a word, let's say "foo", then the program will open this subdirectory and perform a function on the files within the subdirectory. Can anybody give me some help on how to go about this? it also needs to be recursive. Thanks in advance

Upvotes: 1

Views: 862

Answers (1)

Borodin
Borodin

Reputation: 126722

This can be done using the File::Find module, but I believe Path::Class is superior even though it isn't a core module and will likely need installing.

This program finds the files wanted and calls process to process them. At present the process subroutine simply prints the name of the file for testing.

use strict;
use warnings;

use Path::Class;

my $dir = dir '/path/to/root/directory';

$dir->recurse(callback => sub {
  my $node = shift;
  return if $node->is_dir;
  my $parent = $node->parent;
  if ($parent->basename =~ /foo/) {
    process($node);
  }
});

sub process {
  my $file = shift;
  print $file, "\n";
}

Update

If you prefer, this program performs the same task using File::Find.

use strict;
use warnings;

use File::Find;
use File::Basename qw/ basename /;

my $dir = '/path/to/root/directory';

find(sub {
  return unless -f;
  if (basename($File::Find::dir) =~ /foo/) {
    process($File::Find::name);
  }
}, $dir);

sub process {
  my $file = shift;
  print $file, "\n";
}

Update

As requested, here is a further solution using Path::Class::Rule for comparison. As daxim suggested the code is a little shorter.

use strict;
use warnings;

use Path::Class::Rule;

my $rule = Path::Class::Rule->new;
$rule->file->and(sub { $_->parent->basename =~ /foo/ });

my $next = $rule->iter('/path/to/root/directory');
while ( my $file = $next->() ) {
  process($file);
}

sub process {
  my $file = shift;
  print $file, "\n";
}

Upvotes: 3

Related Questions