I am always looking at other people's code to find examples of what I want to do. Where I work we have directories full of code, and I found it a hassle to wade through each directory to grep through the files.

This should also be possible with a combination of xargs and grep, but I liked this solution better, with line numbers and path location included. Also allows users to specify a filename pattern, example searching pl or php or html files.

Comments would be very appreciated.

#!/usr/bin/perl -w # By Greg Flanders gflan@NO.avalon.SPAM.net.THANKS # # Opens each file from currenct directory and searches # for the pattern given. Jumps down directories to search # recursively. use strict; use File::Find; use Cwd; my $directory = getcwd(); my$searchstring = $ARGV[0]; my $ext = $ARGV[1]; print "$searchstring\n"; die "Usage : ggrep searchstring extension\n" if ($searchstring eq ""); find (\&process_file, "$directory"); sub process_file { return if -d; if ($_ =~ /$ext/i) { open (INPUT, "< $_"); foreach (<INPUT>) { if(/$searchstring/i) { $_ = substr($_, 0, 60); s/^\s*//; print "$File::Find::name\:$.\:\t$_\n"; } } close INPUT; } }

Replies are listed 'Best First'.
RE: Recursively grep through directory trees.
by davorg (Chancellor) on Jul 12, 2000 at 14:05 UTC

    Nice code. I do have a couple of suggestions tho'.

    1. Instead of if (-d) {} why not just use return if -d;
    2. You use the variable $count to keep track of the current line number, but Perl already does that for you in the $. variable

    Hope these are helpful.

    --
    <http://www.dave.org.uk>

    European Perl Conference - Sept 22/24 2000, ICA, London
    <http://www.yapc.org/Europe/>
      Thanks for the tips! I've modified the above snippet, including your suggestions, as well as added a few regex's to strip out initial whitespace, as well as added the ability to specify a file extension (actually, a file pattern match).

      For example, I just used "grep checkbox php" to grep all php files for a checkbox.

RE: Recursively grep through directory trees.
by merlyn (Sage) on Jul 12, 2000 at 19:16 UTC
    I think you introduced unneeded complexity here.

    Off the top of my head:

    use File::Find; my ($search, $ext) = @ARGV; $ext = ".$ext" if defined $ext; @ARGV = (); find sub { push @ARGV, $_ if -f and not $ext or /\Q$ext$/ }, "."; while (<>) { close ARGV if eof; print "$ARGV: $. :$_\n" if /$search/; }
    There's a few optimizations with qr// if you're really into speed, but this should handle 90% of it.

    -- Randal L. Schwartz, Perl hacker

RE: Recursively grep through directory trees.
by ZZamboni (Curate) on Jul 12, 2000 at 23:20 UTC
    Pretty good snippet. One thing: you should use while instead of foreach. From the Camel book:
    In a foreach statement, the expression in parenthesis is evaluated to produce a list.
    So when you use foreach(<FILE>) you are slurping the entire file in memory before looping through the files. while on the other hand, would read the file one line at a time, which is good for your purposes.

    --ZZamboni

(jjhorner)Recursively grep through directory trees.
by jjhorner (Hermit) on Jul 12, 2000 at 17:42 UTC

    Well, I made the mistake of voting you ++ before I noticed that you didn't use either 'warnings' or 'strict'.

    ALWAYS USE THESE PRAGMAS!!

    Other than that, pretty good code.

    J. J. Horner
    Linux, Perl, Apache, Stronghold, Unix
    jhorner@knoxlug.org http://www.knoxlug.org/
    
      FWIW: Here is a short discussion that showed me the light.

      Melvin strict bugs me though. especially for short hacks like that one.
      jcwren No no no. strict and -w are your friends. They keep you from chasing down stupid bugs (even in short code) written at 2am in the morning...
      redmist or 5:00am without sleep
      jcwren And, it ceases to be a 'short hack' when you post it. Now, it'll be around for eternity. So, not only should you appease the gods with use strict and -w, but you should make sure your name is plastered in there.
      davorg agrees whole-heartedly with jcwren
      jjhorner Melvin you never know when you may want to bundle all of your short hacks into a library of useful tools. As a matter of fact, I recommend starting that now!
      Melvin thanks for the suggestions, the code has now been strictified and warnified. =)