When I grep my Subversion working copy directory, the results include a lot of files from the .svn directories. Is it possible to recursively grep a directory, but exclude all results from .svn directories?
11 Answers
If you have GNU Grep, it should work like this:
grep --exclude-dir=".svn"
If happen to be on a Unix System without GNU Grep, try the following:
grep -R "whatever you like" *|grep -v "\.svn/*"

- 6,336
- 4
- 29
- 21

- 3,049
- 1
- 15
- 4
-
6On the Windows version of GNU Grep, I had to use `--exclude-dir=\.svn` – gen_Eric Sep 28 '10 at 16:00
-
18
-
6ha. I was just about to upvote but I had already. seems I was here before :) – Darragh Enright Nov 30 '11 at 14:29
-
3+1 for the second example, the first didn't work for me with GNU grep 2.6.3 using `export GREP_OPTIONS="--exclude-dir=\".svn\" -nR --color"` – jperelli Mar 19 '12 at 15:56
-
3
-
As @osgx said, `exclude-dir` doesn't work on my GNU grep 2.5. Instead, the following works well for me as all the accidental matches are within the *.svn-base files: `grep --exclude="*.svn-base"` – user193130 Dec 04 '15 at 15:51
-
Was doing it the latter way, but that lost `--color` support, which made me sad. `--exclude-dir` gets me what I need, and color-coded. – dwanderson Dec 07 '15 at 22:05
-
1An alias to exclude **all** dot-starting dirs: `alias grepexclhid="grep --exclude-dir=\".*\""`. One might even want to make the alias name to be `grep`, then to use it without an alias you'd have to type full path `/usr/bin/grep`. – Hi-Angel Aug 28 '16 at 21:21
For grep >=2.5.1a
You can put this into your environment (e.g. .bashrc
)
export GREP_OPTIONS='--exclude-dir=".svn"'
PS: thanks to Adrinan, there are extra quotes in my version:
export GREP_OPTIONS='--exclude-dir=.svn'
PPS: This env option is marked for deprecation: https://www.gnu.org/software/grep/manual/html_node/Environment-Variables.html "As this causes problems when writing portable scripts, this feature will be removed in a future release of grep, and grep warns if it is used. Please use an alias or script instead."

- 90,338
- 53
- 357
- 513
-
2You don't need to have double quote - it didnt work for me when the double quote is present – Adrian Gunawan Jun 27 '12 at 05:20
-
1GREP_OPTIONS stopped being a supported environment variable after 2.20 – yukashima huksay Jan 24 '21 at 08:01
If you use ack (a 'better grep') it will handle this automatically (and do a lot of other clever things too!). It's well worth checking out.

- 268,207
- 37
- 334
- 440
-
3
-
9Really nice that ack. Careful that, in Ubuntu and Linux Mint, the "ack" package has nothing to do with the "ack - better grep", which is located in the "ack-grep" package. – José Tomás Tocino Sep 18 '12 at 22:16
-
That unfortunately didn't solve problem with *all* hidden dirs *(e.g. I don't want it to descend to `.stack-work` dir)*, also I didn't quite like that its output takes more space by having filenames on a separate line. So I end up making an alias to grep `alias grepexclhid="grep --exclude-dir=\".*\""`. – Hi-Angel Aug 28 '16 at 21:20
psychoschlumpf is correct, but it only works if you have the latest version of grep
. Earlier versions do not have the --exclude-dir
option. However, if you have a very large codebase, double-grep
-ing can take forever. Drop this in your .bashrc
for a portable .svn
-less grep:
alias sgrep='find . -path "*/.svn" -prune -o -print0 | xargs -0 grep'
Now you can do this:
sgrep some_var
... and get expected results.
Of course, if you're an insane person like me who just has to use the same .bashrc
everywhere, you could spend 4 hours writing an overcomplicated bash function to put there instead. Or, you could just wait for an insane person like me to post it online:

- 8,229
- 7
- 45
- 59
-
The method you list above using find and xargs does not work, at least on RHEL5 in my environment. I still get .svn-base listings. – coderintherye Dec 20 '10 at 19:29
grep --exclude-dir=".svn"
works because the name ".svn" is rather unique. But this might fail on a more generalized name.
grep --exclude-dir="work"
is not bulletproof, if you have "/home/user/work" and "/home/user/stuff/work" it will skip both. It is not possible to define "/*/work/*" to restrict the exclusion to only the former folder name. As far as I could experiment, in GNU grep the simple --exclude won't exclude directories.

- 2,508
- 19
- 29
-
1
-
This should be a comment to the accepted answer, not an answer in itself. – Dave Dec 05 '11 at 18:39
-
@Dave: Thanks for the tip. You have just commented on a 2 year old comment. – karatedog Dec 05 '11 at 23:29
On my GNU grep 2.5, --exclude-dirs
is not a valid option. As an alternative, this worked well for me:
grep --exclude="*.svn-base"
This should be a better solution than excluding all lines which contain .svn/
since it wouldn't accidentally filter out such lines in a real file.

- 8,009
- 4
- 36
- 64
-
1Have you noticed difference, this is `--exclude-dir` no `--exclude-dirs`? – shjeff Mar 01 '19 at 13:12
I tried double grep'in on my huge code base and it took forever so I got this solution with the help of my co-worker
Pruning is much faster as it stops find from processing those directories compared to 'grep -v' which processes everything and only excludes displaying results
find . -name .svn -prune -o -type f -print0 | xargs -0 egrep 'YOUR STRING'
You can also alias this command in your .bashrc as
alias sgrep='find . -name .svn build -prune -o -type f -print0 | xargs -0 egrep '
Now simply use
sgrep 'whatever'

- 12,003
- 9
- 51
- 107

- 819
- 9
- 10
Two greps will do the trick:
- The first grep will get everything.
The second grep will use output of first grep as input (via piping). By using the -v flag, grep will select the lines which DON'T match the search terms. Voila. You are left with all the ouputs from the first grep which do not contain .svn in the filepath.
-v, --invert-match Invert the sense of matching, to select non-matching lines.
grep the_text_you_want_to_search_for * | grep -v .svn

- 19
- 1
-
1
-
1Another problem is that it will remove any lines that happen to have ".svn" in them, whether or not the .svn is because of the filename, or is actually in the file. Another problem is that you're spending the time searching the files in the .svn directory that you know you're going to exclude. Better to --exclude from the beginning. – Andy Lester Jun 27 '12 at 18:57
-
This would also waste time finding matches in .svn only to filter them after the fact. – spaaarky21 May 01 '14 at 17:18
For grep version 2.5.1 you can add multiple --exclude
items to filter out the .svn
files.
$ grep -V | grep grep
grep (GNU grep) 2.5.1
GREP_OPTIONS="--exclude=*.svn-base --exclude=entries --exclude=all-wcprops" grep -l -R whatever ./

- 1,192
- 14
- 20
Another option, albeit one that may not be perceived as an acceptable answer is to clone the repo into git and use git grep
.
Rarely, I run into svn repositories that are so massive, it's just impractical to clone via git-svn
. In these rare cases, I use a double grep solution, svngrep, but as many answers here indicate, this could be slow on large repositories, and exclude '.svn' occurrences that aren't directories. I would argue that these would be extremely seldom though...
Also regarding slow performance of multiple greps, once you've used something like git, pretty much everything seems slow in svn!
One last thing.., my variation of svngrep passes through colorization, beware, the implementation is ugly! Roughly grep -rn "$what" $where | egrep -v "$ignore" | grep --color "$what"

- 66,362
- 10
- 68
- 89
I think the --exclude option of recursion is what you are searching for.

- 14,136
- 6
- 46
- 59