Include and Exclude Filters
When running a recursive search (grep -r), grep will attempt to open and read every single file it encounters.
If you run grep -r "function()" /project, grep will waste immense amounts of CPU and I/O reading inside /project/node_modules, /project/.git/objects, and minified build artifacts.
To mitigate this, GNU grep offers flags to filter which files are read.
1. Including Files (--include)
If you know exactly what extensions you care about, use --include with a glob pattern. grep will only open files that match the pattern.
# Only search inside .py and .sh files
grep -r --include="*.py" --include="*.sh" "TODO" /project
2. Excluding Files (--exclude)
If you want to search everything except a few specific types of files, use --exclude.
# Search everything but ignore minified JS and map files
grep -r --exclude="*.min.js" --exclude="*.map" "debug" /project
3. Excluding Directories (--exclude-dir)
Excluding files is helpful, but the real performance killer is traversing massive directories. The --exclude-dir flag tells grep to skip an entire directory tree.
# Do not enter the .git or node_modules directories
grep -r --exclude-dir=".git" --exclude-dir="node_modules" "API_KEY" /project
Best Practice Workflows
Combining these flags is the standard way to search codebases using traditional grep.
# The standard developer grep command
grep -r \
--exclude-dir=".git" \
--exclude-dir="node_modules" \
--exclude-dir="dist" \
--include="*.ts" \
--include="*.tsx" \
"export interface" .
If you look at the command above, you can see why ripgrep (rg) was invented. rg "export interface" automatically applies all of those excludes by reading your .gitignore.
However, understanding --exclude-dir is mandatory for sysadmins working on vanilla UNIX boxes where ripgrep isn't an option.
4. Avoiding Binary Files (-I)
If grep encounters a compiled binary file, an image, or a compressed archive, it will try to read it. If the pattern matches random binary data, grep will output Binary file matches, ruining your output stream.
The -I (capital i) flag tells grep to ignore binary files completely. (This is equivalent to --binary-files=without-match).
# Search securely, ignoring all binary files
grep -r -I "password" /etc