Posts Tagged ‘grep’

A fast grep for Rails

Posted in Home on June 17th, 2007 by mark – 3 Comments

I often want to grep for a word recursively within a directory. That is easy! But quite often I know there are a bunch of directories that I can ignore. For instance, in my rails apps I don’t want to hear about subversion directories and I don’t want to search the vendor tree.

I also don’t want to look at files that are really big – they are usually log files or binaries of some sort that I just don’t care about. So I put together the monster find and grep string that works for me.

find . -path '*/.svn' -prune \
    -o -path '*/vendor' -prune \
    -o -path '*/log' -o -path '*~' -prune \
    -o \( -size -100000c -type f \) \
    -print0 | xargs -0 grep -ne "SEARCH"

Let’s break it down.

find .

start searching for files recurively, starting from the current directory

-path '*/.svn' -prune

ignore .svn directories

-o -path '*/vendor'

OR ignore the vendor directory too.

-o -path '*~'

OR ignore all the emacs backup files

-o -path '*/log' -prune

ignore the log directory

-o \( -size -100000c -type f \)

OR make sure the size is less than 100,000 characters and the type of thing is a file (not a pipe or a director or socket) – this usually gets rid of all non source files

-print0

tells find to terminate the line with a 0. Which sounds really dull, but you can’t pipe the data (get the output from ‘find’ to ‘grep’) if there is a space in the filename.

|

push the data from the command on the left to the command on the right

xargs -0

take the input from the fine command, terminated with a 0 (the print0 from find) and send it to grep.

grep -ne

search each file with a regular expression and when a match is found print the line number with the filename.

The easiest way to use this is to put it into a shell file – I’ve put it into s.sh.

My s.sh file looks like this

#!/bin/sh

if  [ ${#1} -gt 0  ]
then
    find . -path '*/.svn' -prune -o -path '*/vendor' -prune -o -path '*/log' -o -path '*~' -prune -o \( -size -100000c -type f \) -print0 | xargs -0 grep -ne  $1
else
    echo "Not enough parameters.  Usage: ./$0 searchstring"
fi

Then I make it executable by

chmod 755 s.sh

If you want to find all of the before filters you would do this

s.sh “before_filter”

and enjoy you super fast find command.