I am searching through a Ruby on Rails application for a word using grep on OSX, and I would like to exclude directories that match a certain pattern.

I am using the following command:

grep -inRw -E 'direct' . --exclude-dir -E 'git|log|asset'

This command is not doing what I thought it would do. Here is how I thought it would work:

  • i - case insensitive search
  • n - print line number in which pattern is found
  • R - search recursively
  • w - I only want whole words - i.e., match "direct" but not "directory"
  • -E - use extended regular expression
  • 'direct' - the regular expression I want to match
  • . - search in the current directory
  • --exclude-dir -E 'git|log|asset' - exclude directories that match git or log or asset.

In terms of the exclude directories, the command still ends up searching in the './git' and './log' directories, as well as in './app/assets'

I'm obviously lacking a fundamental piece of knowledge, but I do not know what it is.

4 Answers 4


It's pattern as in globs not pattern as in regex. Per the info page:


Skip any command-line directory with a name suffix that matches the pattern GLOB. When searching recursively, skip any subdirectory whose base name matches GLOB. Ignore any redundant trailing slashes in GLOB.

So, you either use the switch multiple times or, if your shell supports brace expansion, you could golf it shorter and have the shell expand the list of patterns e.g.:

grep -inRw -E 'direct' . --exclude-dir={git,log,assets}

to exclude directories named git, log and assets or e.g.

grep -inRw -E 'direct' . --exclude-dir={\*git,asset\*}

to exclude directory names ending in git or starting with asset.

Note that the shell expands the list only if there are at least two dirnames/globs inside braces.

  • Very interesting. I guess I should look up what a glob is.
    – Steven L.
    May 12, 2016 at 0:24
  • 1
    I'm sorry but none of these seem to be working. Would it help if I if I said that I'm using this version of grep: grep (BSD grep) 2.5.1-FreeBSD?
    – Steven L.
    May 12, 2016 at 1:10
  • I'm stumped because I'm reading the manual for bsd grep (freebsd.org/cgi/man.cgi?query=grep&sektion=&n=1) and there's not mention of --exclude-dir. Boo.
    – Steven L.
    May 12, 2016 at 2:21
  • 2
    OK - I see the problem now. This must be a modified version of grep used by the Apple system only. I am on Mac OS X. I'm sorry for the confusion here. I'm sure there's a forum somewhere else on stackexchange I can post to.
    – Steven L.
    May 12, 2016 at 2:23
  • @user245185 are you on BSD or on OSX? Both are on topic here, but please edit your question and tell us what OS you are using. The behaviors of the standard tools differ between implementations as you're discovering.
    – terdon
    May 12, 2016 at 8:49

--exclude-dir does not understand |.

You can, however, get the same effect by specifying --exclude-dir multiple times, one for each directory that you want to exclude:

grep -inRw -E --exclude-dir 'asset' --exclude-dir 'git' --exclude-dir 'log' 'direct'
  • 1
    It worked for me. I wanted to exclude home directory but it didn't work with other options like --exclude-dir={home}. I worked when I typed --exclude-dir 'home' Aug 14, 2019 at 10:05
  • I can confirm that Mubin, the parentheses {...} don't have any effect for me either.
    – Andreas L.
    Oct 21, 2020 at 12:27
  • 1
    @MubinIcyer @AndreasL. Just a thought: {…} is a Bash construct — so if you have a different shell, it may not support it. 🤔 linux.com/topic/desktop/all-about-curly-braces-bash Oct 27, 2022 at 10:48
  • @MubinIcyer you must have at least 2 globs, e.g. --exclude-dir={home,somethingelse}. See unix.stackexchange.com/q/433729
    – igor
    Oct 12, 2023 at 9:44

This is what I was doing wrong: input to --exclude-dir is dir-name(s) and not pathname(s). directory names cannot contain /.

Following works:

grep -r --exclude-dir={cache,lib} pattern /home/ /var/

Following doesn't work:

grep -r --exclude-dir={/var/cache,/var/lib} pattern /home/ /var/

Please use this:

grep -inRw -E 'direct' folder/ --exclude-dir={\*git\*,\*log\*,\*assets\*}

or current folder

grep -inRw -E 'direct' . --exclude-dir -E 'git|log|asset'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .