Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Search directory recursive with regex

by Anonymous Monk
on Mar 02, 2015 at 18:50 UTC ( [id://1118457]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to use something like File::Find::Rule to get rid of some code that has the UNIX find command in it.

Working code:

sub AllInFilesystemResults { my ($class) = shift; my ($collectArchive) = shift; my @searchLocations; if ( $collectArchive =~ /^archive/ ) { @searchLocations = "/vol/$collectArchive/prod/*"; } else { @searchLocations = ( "/vol/archive*/prod/*/$collectArchive/*", "/vol/archive*/prod/system/archive/$collectArchive/*" ); } my %listOfFilesDatabase; foreach my $searchLocation (@searchLocations) { my @archivesInFilesystem = `find $searchLocation -type f 2> /dev/null | grep -v \"\/archive\/archive\/\"`; chomp @archivesInFilesystem; $searchLocation = qr/$searchLocation/; foreach my $locationFS (@archivesInFilesystem) { print "$locationFS\n"; utf8::decode($locationFS); $listOfFilesDatabase{$locationFS}++; } } return %listOfFilesDatabase; }

I would like @searchLocations to be regex that then gets searched through

if ( $collectArchive =~ /^archive/ ) { @searchLocations = "/vol/$collectArchive/prod/.+"; } else { @searchLocations = ( "/vol/archive\\d{2}/prod/.+/$collectArchive/.+", "/vol/archive\\d{2}/prod/system/archive/$collectArchive/.+" ); } my %listOfFilesDatabase; foreach my $searchLocation (@searchLocations) { $searchLocations = qw/$searchLocation/;

Replies are listed 'Best First'.
Re: Search directory recursive with regex
by Anonymous Monk on Mar 02, 2015 at 22:43 UTC

    Although I agree that using Perl instead of calling find is probably better, I'm not sure if File::Find::Rule directly supports the operation you are looking for; you might have to build something that lists those paths yourself, but Path::Class or most likely Path::Tiny (see its children method) would probably be very helpful there.

    Or, maybe in this case glob can help? (make sure to read its documentation, including File::Glob)

    use File::Find::Rule; my @searchLocations = ( glob("/vol/archive[0-9][0-9]/prod/*/$collectArchive/*"), glob("/vol/archive[0-9][0-9]/prod/system/archive/$collectArchive/*") ); my @files = File::Find::Rule->file->in(@searchLocations);

    By the way, as a side note, in your example regexes, .+ is probably better written as [^\/]+, because otherwise it may match any number of slashes as well.

      Two step solution is clever, saves work, here is the other way , direct translation
      #my @archivesInFilesystem = # `find $searchLocation -type f 2> /dev/null # | grep -v \"\/archive\/archive\/\"`; use File::Find::Rule qw/ find rule / my $keepers = sub { ## $_ is like $fullname ## my( $shortname, $path, $fullname ) = @_; ## return !!1 if $fullname =~ m{/archive/archive/}; # keeper return !!1 if m{/archive/archive/}; # keeper return !!0; # goner };; my @archivesInFilesystem = find( file => exec => $keepers, in => $searchLocation, );

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1118457]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-03-28 23:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found