Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

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
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?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (13)
As of 2014-09-16 15:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (33 votes), past polls