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

Hi monks, I would like to write a perl script to Recursively search down thru directories and to find a string in all the files it could find and display all the file locations where the string is found. The string has to be taken from a file. Thanks, Sharath
  • Comment on How to Recursively search down thru directories to find a string and display its location.

Replies are listed 'Best First'.
Re: How to Recursively search down thru directories to find a string and display its location.
by stevieb (Canon) on May 17, 2012 at 06:39 UTC

    You'll be pleased to know that File::Find has already been written to take care of the hard part of what you're looking for, you just have to add in the code you've written to check each file for the content.

    If you haven't written the code that searches each file for content, running the command perldoc -f grep will put you on the right track. Although there are better and newer ways to do it nowadays, that will at least get you started. If you'd like to move forward, post what work you've done.

Re: How to Recursively search down thru directories to find a string and display its location.
by roboticus (Chancellor) on May 17, 2012 at 10:30 UTC

    sharathfierof2:

    If you're running on *NIX, or have cygwin or equivalent installed for windows, you don't even need a script. You could use:

    find /path -type f -print0 | xargs -0 grep 'string'

    ...or use the simpler statement shown by AM (next response).

    Update: Corrected OPs name, added previous sentence.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: How to Recursively search down thru directories to find a string and display its location.
by diddy_perl (Novice) on May 17, 2012 at 08:31 UTC

    Here is a sample code:

    use strict; use File::Find; my @dirs = qw( . ); ## add current directory to list of + dirs to search ## main processing done here my @found_files = (); my $pattern = qr/World/; find( \&wanted, @dirs ); ## fullpath name in $File::Find::name sub wanted { next if $File::Find::name eq '.' or $File::Find::name eq '..'; + open my $file, '<', $File::Find::name or die "Error openning file: + $!\n"; while( defined(my $line = <$file>) ) { if($line =~ /$pattern/) { push @found_files, $File::Find::name; last; } } close ($file); } ## display files - could be sorted if needed, etc foreach my $file( @found_files) { print $file, "\n"; }
      next if $File::Find::name eq '.' or $File::Find::name eq '..';

      $File::Find::name contains the full path name so (in your example) it would start at ./. and continue with ./subdir/. etc. and would never match . or ...    Also you should use return when exiting from a subroutine.    Probably better as:

      return unless -f;


      open my $file, '<', $File::Find::name or die "Error openning file: + $!\n";

      Also, because File::Find::find() changes directories, trying to open $File::Find::name from the current directory when using relative directory names won't work.    Just use the file name in $_:

      open my $file, '<', $_ or die "Error openning '$_' $!\n";
Re: How to Recursively search down thru directories to find a string and display its location.
by Anonymous Monk on May 17, 2012 at 11:14 UTC
    grep -ri dirname 'string'