benny.bennett
benny.bennett

Reputation: 710

Perl Subdirectory Traversal

I am writing a script that goes through our large directory of Perl Scripts and checks for certain things. Right now, it takes two kinds of input: the main directory, or a single file. If a single file is provided, it runs the main function on that file. If the main directory is provided, it runs the main function on every single .pm and .pl inside that directory (due to the recursive nature of the directory traversal).

How can I write it (or what package may be helpful)- so that I can also enter one of the seven SUBdirectories, and it will traverse ONLY that subdirectory (instead of the entire thing)?

Upvotes: 1

Views: 610

Answers (3)

Lumi
Lumi

Reputation: 15314

One convenient way would be to use the excellent Path::Class module, more precisely: the traverse() method of Path::Class::Dir. You'd control what to process from within the callback function which is supplied as the first argument to traverse(). The manpages has sample snippets.

Using the built-ins like opendir is perfectly fine, of course.

I've just turned to using Path::Class almost everywhere, though, as it has so many nice convenience methods and simply feels right. Be sure to read the docs for Path::Class::File to know what's available. Really does the job 99% of the time.

Upvotes: 1

Dave Cross
Dave Cross

Reputation: 69314

I can't really see the difference in processing between the two directory arguments. Surely, using File::Find will just do the right thing in both instances.

Something like this...

#!/usr/bin/perl

use strict;
use warnings;

use File::Find;

my $input = shift;

if (-f $input) {
  # Handle a single file
  handle_a_file($input);
} else {
  # Handler a directory
  handle_a_directory($input);
}

sub handle_a_file {
  my $file = shift;

  # Do whatever you need to with a single file
}

sub handle_a_directory {
  my $dir = shift;

  find(\&do this, $dir);
}

sub do_this {
  return unless -f;
  return unless /\.p[ml]$/;

  handle_a_file($File::Find::name);
}

Upvotes: 2

Reza S
Reza S

Reputation: 9768

If you know exactly what directory and subdirectories you want to look at you can use glob("$dir/*/*/*.txt") for example to get ever .txt file in 3rd level of the given $dir

Upvotes: 1

Related Questions