http://www.perlmonks.org?node_id=1024421

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.

Replies are listed 'Best First'.
Re: traverse directory recursively and search for pattern
by rjt (Curate) 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