Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot

traverse directory recursively and search for pattern

by besogon (Initiate)
on Mar 20, 2013 at 03:08 UTC ( #1024421=perlquestion: print w/ replies, xml ) Need Help??
besogon has asked for the wisdom of the Perl Monks concerning the following question:

Hello, i am brand new to perl. I need help with a script that search for a given regex pattern in a given directory recursively. Also, i need to bypass non ASCI (binary) files. I appreciate your help. God bless.

Comment on traverse directory recursively and search for pattern
Replies are listed 'Best First'.
Re: traverse directory recursively and search for pattern
by rjt (Deacon) on Mar 20, 2013 at 03:58 UTC

    File::DirWalk makes the directory recursion easy. Perl's builtins trivialize the rest. The canonical way to use DirWalk is something like so:

    #!/usr/bin/env perl use 5.014; use warnings; use File::DirWalk; # Process commandline arguments die "usage: $0 pattern path ..." if (@ARGV < 2); my $pattern = shift; # @ARGV now contains one or more paths to recurse # Set up DirWalk object with callback to grep each file my $dw = new File::DirWalk; $dw->onFile(sub { my $file = shift; if (-T $file) { open my $fh, '<', $file or die "Can't open $file: $!"; print map { "$file: $_" } grep { /$pattern/ } <$fh>; close $fh; } return File::DirWalk::SUCCESS; }); $dw->walk($_) for @ARGV;

    The above gives you a very simple grep -R command. Probably more instructive than directly useful.

    The -T operator is one of Perl's file test operators that evaluates to true if the file is an ASCII text file (based on some heuristic guesswork). There is an equivalent -B test for binary files.

Re: traverse directory recursively and search for pattern
by kielstirling (Scribe) on Mar 20, 2013 at 04:28 UTC
    I do this like so. ;)
    #!/usr/bin/perl use Modern::Perl; use autodie; my ($dir, $match) = @ARGV; die "directory does not exists $dir" unless -d $dir; die "No match" unless $match; open_readdir($dir, \&process); sub process { my ($dir, $file) = @_; if (-T "$dir/$file") { open my $fh, '<', "$dir/$file"; say "$dir/$file: $_" for grep /$match/, $fh->getlines; $fh->close; } } sub open_readdir { (my $dir = shift) =~ s/\/$//; my $code = shift; my $db; opendir $dh, $dir; my @files = grep !/^\./, readdir $dh; for my $file (@files) { if (-d "$dir/$file") { open_readdir("$dir/$file", \&process); } else { &$code($dir, $file); } } closedir($dh); }
Re: traverse directory recursively and search for pattern
by Anonymous Monk on Mar 20, 2013 at 07:32 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1024421]
Approved by vinoth.ree
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2016-02-14 10:24 GMT
Find Nodes?
    Voting Booth?

    How many photographs, souvenirs, artworks, trophies or other decorative objects are displayed in your home?

    Results (470 votes), past polls