karate_kid
karate_kid

Reputation: 155

Recursive unique search in particular sub directories - Perl

Here's my directory structure..

                                    Current
                   /                    |                       \
           a                            d                       g
        /      \                   /             \              | 
        b       c                e              morning         evenin
       /  \    /   \             |
     hello hi  bad good          f
                                 /  \   
                               good night

Where current, a,b,c,d,e, f,g are directories and other are files. Now I want to recursively search in current folder such that the search shouldn't be done only in g folder of current directory. Plus, as 'good' file is same in current-a-c-good and current-d-e-f-good, the contents of it should be listed only once. Can you please help me how to do it?

Upvotes: 0

Views: 176

Answers (2)

Birei
Birei

Reputation: 36262

The suggestion of Paulchenkiller in comments is fine. The File::Find module searchs recursively and lets to handle easily what to do with files and directories during its traverse. Here you have something similar to what you are looking for. It uses preprocess option to prune the directory and the wanted option to get all file names.

#!/usr/bin/env perl

use strict;
use warnings;
use File::Find;

my (%processed_files);

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

for ( keys %processed_files ) { 
        printf qq|%s\n|, $_;
}

sub dir_preprocess {
        my (@entries) = @_; 
        if ( $File::Find::dir eq '.' ) { 
                @entries = grep { ! ( -d && $_ eq 'g' ) } @entries;
        }   
        return @entries;
}

sub wanted {
        if ( -f && ! -l && ! defined $processed_files{ $_ } ) { 
                $processed_files{ $_ } = 1;
        }   
}

Upvotes: 1

René Kolařík
René Kolařík

Reputation: 1286

my $path = "/some/path";
my $filenames = {};

recursive( $path );

print join( "\n", keys %$filenames );

sub recursive
{
    my $p = shift;
    my $d;

    opendir $d, $p;

    while( readdir $d )
    {
        next if /^\./; # this will skip '.' and '..' (but also '.blabla')

        # check it is dir
        if( -d "$p/$_" )
        {
            recursive( "$p/$_" );
        }
        else
        {
            $filenames->{ $_ } = 1;
        }
    }

    closedir $d;
}

Upvotes: 0

Related Questions