Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When using Perl's File::Find what's a quick & easy way to limit search depth?

I want to be able to limit Perl's File::Find to a directory depth (below the specified search) to the specified directory and 1 & 2 subdirectories beneath it.

I want to be able to enumerate the files at the same time, if this is possible.

It must work with absolute paths.

like image 916
unixman83 Avatar asked Mar 29 '12 06:03

unixman83


People also ask

How do I read the contents of a file in Perl?

The main method of reading the information from an open filehandle is using the operator < >. When < > operator is used in a list context, it returns a list of lines from the specified filehandle. The example below reads one line from the file and stores it in the scalar. $firstchar = getc (fh);

How do I find a file path in Perl?

Find all dirs:use File::Find; my @files; my @dirpath=qw(/home/user1); find(sub { push @files,$File::Find::name if (-d $File::Find::name ); }, @dirpath); print join "\n",@files; The directories alone are filtered by checking for the -d option against the $File::Find::name variable.

How do I open a file for reading in Perl?

Following is the syntax to open file.open(DATA, "<file. txt"); Here DATA is the file handle, which will be used to read the file. Here is the example, which will open a file and will print its content over the screen.


1 Answers

This perlmonks node explains how to implement mindepth and maxdepth from GNU's find.

Basically, they count the number of slashes in a directory, and use that to determine the depth. The preprocess function will then only return the values where the depth is smaller than the max_depth.

my ($min_depth, $max_depth) = (2,3);

find( {
    preprocess => \&preprocess,
    wanted => \&wanted,
}, @dirs);

sub preprocess {
    my $depth = $File::Find::dir =~ tr[/][];
    return @_ if $depth < $max_depth;
    return grep { not -d } @_ if $depth == $max_depth;
    return;
}

sub wanted {
    my $depth = $File::Find::dir =~ tr[/][];
    return if $depth < $min_depth;
    print;
}

Tailored to your case:

use File::Find;
my $max_depth = 2;

find( {
    preprocess => \&preprocess,
    wanted => \&wanted,
}, '.');

sub preprocess {
    my $depth = $File::Find::dir =~ tr[/][];
    return @_ if $depth < $max_depth;
    return grep { not -d } @_ if $depth == $max_depth;
    return;
}

sub wanted {
    print $_ . "\n" if -f; #Only files
}
like image 151
Konerak Avatar answered Sep 25 '22 14:09

Konerak