Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I want to find all occurences of foo in a large file system maintained by SVN but I don't want to match anything contained in any .svn directory.

I get immediate matches when I do grep -l -e 'foo' * but when I try and exclude the svn directories with grep -l -e 'foo' --exclude-dir=".svn" the command just hangs.

What am I doing wrong?

share|improve this question

5 Answers 5

up vote 7 down vote accepted

--exclude-dir does not supplant the need to list files on the command line. You are "hanging" because grep is waiting for standard input.

grep -l -e 'foo' --exclude-dir=".svn" *

Consider using ack, which excludes .svn and similar folders (and has many other features) by default.

share|improve this answer
1  
Cleaner if you change * to ., in case there are other hidden folders that should be searched. –  Kevin Apr 2 '12 at 17:51
    
or perhaps you want to use --recursive . instead, seeing as the OP already has GNU grep. –  jw013 Apr 2 '12 at 17:53
    
Personally, I have shopt -s dotglob in Bash, so * already contains dot-files. -r is nice, but ack does that by default too :) –  ephemient Apr 2 '12 at 17:54

If you do not want to grep into directories such as .svn ever you can set the $GREP_OPTIONS variable to exclude it as below:

export GREP_OPTIONS="--exclude-dir=\*/.svn/\*"

Just add this line to your .bashrc and your recursive greps will no more enter into .svn directories. Of course, it can be as rich as you want:

export GREP_OPTIONS="--exclude-dir=\*/.svn/\* --exclude-dir=\*/.hg/\* --exclude-dir=\*/.git/\* --exclude=\*~"
share|improve this answer

You might be interested in ack. It does recursive searching (and other grep-like operations), and excludes directories such as .svn or .git by default.

share|improve this answer

Here's an awk solution as well:

find . | awk '$0 !~ /.svn/{print}' | awk '/foo/{print}'

Basically, from all files, prune those that match /.svn/ and then, out of those, print only these ones that match /foo/. I also like this solution as you can easily use the results with ls. For example, you can use

ls -tl $(find . | awk '$0 !~ /.svn/{print}' | awk '/foo/{print}')

to see a list view sorted by modification date. Also, it's nice to have the full path of the results if you want to do something else with them (open them, execute, etc.)

share|improve this answer

The grep --exclude-dir... solution should be fine, but just to show another way, you can do this with find's -prune:

find -name .svn -prune -o -type f -exec grep -l "$pattern" {} +

If you want to execute something further, find is better than a plain grep -r:

find -name .svn -prune -o -type f -exec grep -q "$pattern" {} \; -exec ./process {} \;
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.