How can I exclude directories from grep -R?
If you are grepping for code in a git repository and node_modules is in your .gitignore , git grep «STUFF» is the easiest way. git grep searches the tracked files in the working tree, ignoring everything from .gitignore
An example for node: grep -R —exclude-dir=
14 Answers 14
which excludes directories matching the pattern dir from recursive directory searches.
grep -R --exclude-dir=node_modules 'some pattern' /path/to/search
For a bit more information regarding syntax and usage see
For older GNU Greps and POSIX Grep, use find as suggested in other answers.
Or just use ack (Edit: or The Silver Searcher) and be done with it!
Syntax for the impatient: —exclude-dir=dir uses grep ‘s regular expression patterns, not shell’s file globbing. Patterns work on paths relative to your current directory. So use pattern —exclude-dir=dir , not —exclude-dir=»/root/dir/*» .
If you wish to exclude multiple dirs from the search, is there a better option than to use : $ grep -r —exclude-dir=dir1 —exclude-dir=dir2 «string» /path/to/search/dir ?
I probably spent way too much time on this than any sane person, but I can’t for the life of me figure out how to exclude a subdirectory from the search — grep -r —exclude-dir=public keyword . works, but grep -r —exclude-dir=’public/dist’ keyword . does not. I tried adding regex wildcards, escaping characters etc, but nothing seems to help.
SOLUTION 1 (combine find and grep )
The purpose of this solution is not to deal with grep performance but to show a portable solution : should also work with busybox or GNU version older than 2.5.
Use find , for excluding directories foo and bar :
find /dir \( -name foo -prune \) -o \( -name bar -prune \) -o -name "*.sh" -print
Then combine find and the non-recursive use of grep , as a portable solution :
find /dir \( -name node_modules -prune \) -o -name "*.sh" -exec grep --color -Hn "your text to find" <> 2>/dev/null \;
SOLUTION 2 (using the —exclude-dir option of grep ):
You know this solution already, but I add it since it’s the most recent and efficient solution. Note this is a less portable solution but more human-readable.
grep -R --exclude-dir=node_modules 'some pattern' /path/to/search
To exclude multiple directories, use —exclude-dir as:
SOLUTION 3 (Ag)
If you frequently search through code, Ag (The Silver Searcher) is a much faster alternative to grep, that’s customized for searching code. For instance, it automatically ignores files and directories listed in .gitignore , so you don’t have to keep passing the same cumbersome exclude options to grep or find .
this combination searches faster than —exclude-dir=dir and it shows results with colors — easy to read
«this combination» find . -exec is not faster than grep —exclude-dir for me. Huge advantage to grep (about five times faster with 26k+ files, filtered out of 38k+ on an HDD), unless you replace the \; with + for the find/exec combo. Then grep is «only» about 30% faster. The grep syntax is also human-readble :).
If you want to exclude multiple directories:
«r» for recursive, «l» to print only names of files containing matches and «i» to ignore case distinctions :
grep -rli --exclude-dir= keyword /path/to/search
Example : I want to find files that contain the word ‘hello’. I want to search in all my linux directories except proc directory, boot directory, sys directory and root directory :
grep -rli --exclude-dir= hello /
Note : The example above needs to be root
Note 2 (according to @skplunkerin) : do not add spaces after the commas in
is expanded by the shell (e.g. Bash), not by grep , into this:
--exclude-dir=dir1 --exclude-dir=dir2
Quoting will prevent the shell from expanding it, so this won’t work:
The patterns used with —exclude-dir are the same kind of patterns described in the man page for the —exclude option:
--exclude=GLOB Skip files whose base name matches GLOB (using wildcard matching). A file-name glob can use *, ?, and [. ] as wildcards, and \ to quote a wildcard or backslash character literally.
The shell will generally try to expand such a pattern itself, so to avoid this, you should quote it:
You can use the curly braces and quoted exclude patterns together like this:
If you are grepping for code in a git repository and node_modules is in your .gitignore , you can use git grep . git grep searches the tracked files in the working tree, ignoring everything from .gitignore
This is an incredible way to limit wading through tons of generated files (dist, bin, etc.) and it pipes into a utility like less automagically so you have a scrollable search result. Fantastic!
Frequently use this:
grep can be used in conjunction with -r (recursive), i (ignore case) and -o (prints only matching part of lines). To exclude files use —exclude and to exclude directories use —exclude-dir .
Putting it together you end up with something like:
grep -rio —exclude= \ —exclude-dir=
Describing it makes it sound far more complicated than it actually is. Easier to illustrate with a simple example.
Suppose I am searching for current project for all places where I explicitly set the string value debugger during a debugging session, and now wish to review / remove.
I write a script called findDebugger.sh and use grep to find all occurrences. However:
For file exclusions — I wish to ensure that .eslintrc is ignored (this actually has a linting rule about debugger so should be excluded). Likewise, I don’t want my own script to be referenced in any results.
For directory exclusions — I wish to exclude node_modules as it contains lots of libraries that do reference debugger and I am not interested in those results. Also I just wish to omit .idea and .git hidden directories because I don’t care about those search locations either, and wish to keep the search performant.
So here is the result — I create a script called findDebugger.sh with:
#!/usr/bin/env bash grep -rio --exclude= \ --exclude-dir= debugger .
How to Exclude Matches with grep
Grep stands for “global regular expression print” has been a widely used command in the Linux platform. It has been utilized to do a lot of functions while using different flag keywords. The grep command with “-v” can be used in several ways to exclude the matches from the files. Let’s have a sharp look at each one of them one by one. Firstly you must have some text file to perform the grep command on it. So we have been using the “new.txt” file that exists in our home directory. Thus, we have to use the “cat” query in the console to display the data of this file. The file contains a total of 6 lines, as illustrated in the image.
Exclude Using Single Pattern
The very first method to exclude the described pattern from the file is using the “-v” flag within the “grep” instruction is the easiest and simple one. In this command, we will be displaying all the contents of a file using “cat” instruction and exclude those lines of text which are matched from the defined one. The grep and cat command has been separated by a separator line. So, we have been using the pattern “CSS” in the query. All the lines which contain the pattern “CSS” within them would be excluded from the output data. Thus, all the remaining lines will be displayed on the shell. The output shows that there is no line in the resultant data containing the pattern “CSS”. The command is displayed in the image.
Another way to use the same grep command is without the “cat” instruction. In this way, you have to only mention the pattern within inverted commas after the flag “-v” and add the file name after it. The grep command will exclude the matched pattern lines and display the remaining ones in the shell. The output is as expected as per the image beneath.
Let’s use another excluding pattern in the grep command to exclude the lines. So, we have used the string “is” instead of “CSS” this time. As the word “is” is used a lot in the file, it excluded all the 4 lines containing the word “is” in the output. Thus, only 2 lines remained to be displayed on the shell.
Let’s see how the grep command works on the new excluding pattern this time. So, we have utilized the pattern “e” in the command to be excluded. The output shows nothing. This demonstrates that the pattern has been found in every line of the file as we know that the alphabet “e” has been most used in words. Hence, there is nothing left to be displayed on the console from the file new.txt.
Exclude Using Multiple Patterns
The above examples illustrate excluding texts from the files with a single pattern mentioned in the command. Now, we will be using the multiple patterns in the same syntax of commands to see how it works. So, we have used the very first syntax of the grep command to exclude the lines from the file “new.txt” and display the remaining lines. We have used the 2 patterns to be searched and then excluded from the file, i.e., “CSS” and “is”. The patterns have been defined with the flag “-e” separately. As the 5 lines of the new.txt file contain both the patterns, it only displays the remaining 1 line in the terminal as displayed.
Let’s use the other syntax of the grep query in the shell to exclude the matching patterns or related lines while using the multiple patterns. So, we have been using the pattern “text” and “is” in the command to exclude the lines from the file “new.txt”. The output of this query displays the single line left that has no word matched with the specified pattern.
There is another unique way to exclude the multiple patterns from the file using the grep command. The command is almost the alike with a slight change. You have to add the alphabet “E” with the flag “-v”. After that, you have to add the multiple patterns to be excluded within the inverted commas separated by a separator line. The example command is shown below. We searched for the patterns “t” and “k” from the file new.txt to exclude the lines containing these patterns. In return, we have left with only 3 lines that are displayed in the image.
Exclude Using Case Sensitive Flag
Like the “-v” flag, you can also use a case-sensitive flag in the grep command to exclude the pattern. It will work similarly as it works for the “-v” flag but with more accuracy. You may use it as per your desire. So, we have been using the “-I” flag with the “-v” flag in the command. To search for the pattern “text” in the file “new.txt”. This file contains a line having the string “text” in it as a whole. Hence, the whole line has been excluded from the file using the command below.
Let’s use another file to exclude patterns from it. The data of this file has been displayed below.
Let’s use the same case-sensitive flag command to exclude the lines that contain the pattern “text” in the file. In return, the texted lines have been removed, and only the dotted lines are left displayed.
Conclusion
This article contains different ways to use the Linux grep command to exclude matching patterns from the files. We elaborated several examples to clarify the concept of grep to exclude matches. We hope that you will find this article great while exploring the “grep” exclude pattern command in Linux.
About the author
Omar Farooq
Hello Readers, I am Omar and I have been writing technical articles from last decade. You can check out my writing pieces.