Skip to main content

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" .
Why Ripgrep Exists

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