grep Recursive Search in Linux (Examples, Include/Exclude, Multiple Patterns)

grep Recursive Search in Linux (Examples, Include/Exclude, Multiple Patterns)

What is Recursive Search in grep

By default, the grep command searches for a pattern only inside the files provided as input. However, in many real-world situations you may need to search inside entire directories containing multiple sub-directories and files.

Recursive search allows grep to scan all files inside a directory including its nested sub-directories automatically.

This is commonly used when:

  • Searching configuration values inside /etc
  • Finding errors in application logs spread across folders
  • Locating specific code snippets inside large source repositories
  • Auditing multiple files for a particular keyword

Without recursive search you would need to manually specify every file or combine grep with other tools such as find.

The grep command provides built-in options to perform recursive searches, making it easy to locate patterns across large directory structures.


Basic Syntax to Run grep Recursively

The general syntax to run grep recursively is:

bash
grep [OPTIONS] PATTERN PATH

Where:

  • PATTERN – string or regex to search
  • PATH – directory where the search should start

Using -r option to search recursively

The -r or --recursive option tells grep to search all files inside the directory and its sub-directories.

Example:

bash
grep -r "error" /var/log

This command searches for the word error in all files under /var/log, including every sub-directory.

Using --recursive option

The --recursive option works exactly the same as -r and is simply the long form of the same argument.

bash
grep --recursive "error" /var/log

Both commands produce identical results.

Normally grep -r does not follow symbolic links inside directories. If you want grep to also search files referenced by symbolic links, you can use the -R option.

bash
grep -R "error" /var/log

This command searches recursively and also follows any symbolic links it encounters.

Difference between -r and -R in grep

OptionBehaviour
-r or --recursiveSearches directories recursively but ignores symbolic links unless specified directly
-R or --dereference-recursiveSearches directories recursively and follows symbolic links

In most situations -r is sufficient. However, if your directory structure contains symbolic links pointing to other files or directories, -R ensures those files are also included in the search.


Quick Reference Table for Recursive grep Options

Command ExampleDescription
grep -r "error" /var/logSearch for a pattern recursively inside a directory and all its sub-directories
grep -r "error" .Search recursively inside the current directory
grep -rn "error" /var/logSearch recursively and display line numbers
grep -ri "error" /var/logPerform recursive search ignoring case differences
grep -rw "error" /etcSearch recursively for an exact word match
grep -rl "error" /var/logList only filenames that contain the matching pattern
grep -rL "error" /var/logList files that do not contain the pattern
grep -rc "error" /var/logCount occurrences of a pattern in each file recursively
grep -rH "error" /var/logShow filename along with matching lines
grep -r --include="*.conf" "error" /etcSearch recursively only in files matching a specific extension
grep -r --include="*.log" "failed" /var/logSearch recursively only in log files
grep -r --include="*.sh" "sudo" /homeSearch recursively only in shell script files
grep -r --exclude="*.log" "error" /var/logExclude specific files during recursive search
grep -r --exclude="*.gz" "error" /var/logSkip compressed files while searching
grep -r --exclude-dir=".git" "TODO" .Exclude directories from recursive search
grep -r --exclude-dir="node_modules" "config" .Ignore large dependency directories during recursive search
grep -r -e "error" -e "failed" /var/logSearch recursively for multiple patterns
grep -r -v "debug" /var/logRecursively show lines that do not match the pattern
grep -r -A3 "error" /var/logShow 3 lines after each recursive match
grep -r -B2 "error" /var/logShow 2 lines before each recursive match
grep -r -C2 "error" /var/logShow lines before and after each match
grep -r -n --color "error" /var/logHighlight matching pattern in recursive search
grep -r -s "error" /var/logSuppress permission errors during recursive search
grep -R "error" /var/logSearch recursively and follow symbolic links
grep -r --binary-files=without-match "error" /var/logSkip binary files during recursive search
grep -r --exclude-dir={proc,sys} "error" /Exclude multiple directories from recursive search

Simple Examples to Use grep Recursively

Search for a string in all files recursively

To search for a pattern inside all files and sub-directories, use the -r option.

bash
grep -r "error" /var/log

This command searches for the word error in every file under /var/log, including all nested directories.

Search inside current directory recursively

If you want to search inside the current working directory and all its sub-directories, use . as the path.

bash
grep -r "error" .

This is commonly used when searching inside project folders or source code directories.

Search inside a specific directory recursively

You can provide the path of any directory where the recursive search should begin.

bash
grep -r "timeout" /etc

This command searches for the word timeout in all configuration files under /etc and its sub-directories.

Search recursively with line numbers

To display the line number where the pattern appears, combine recursive search with -n.

bash
grep -rn "error" /var/log

This helps quickly identify the exact location of the match inside a file.


Grep Recursive Search with Case Insensitive Pattern

Ignore case while searching recursively

By default grep is case-sensitive. To ignore case differences, use the -i option.

bash
grep -ri "error" /var/log

This command matches error, Error, ERROR, and any other case variation.

Match exact word only while searching recursively

If you want to match only the exact word instead of partial matches, use the -w option.

bash
grep -rw "error" /var/log

This ensures that grep matches error but ignores words like errors or terror.


Grep Recursive Search in Specific File Types

Search only inside .conf files

You can limit recursive searches to specific file types using --include.

bash
grep -r --include="*.conf" "timeout" /etc

This command searches only inside .conf files while ignoring other file types.

Search only inside .log files

To search for patterns in log files only:

bash
grep -r --include="*.log" "failed" /var/log

This is useful for troubleshooting application or system logs.

Search inside multiple file extensions

You can provide multiple --include arguments to search across different file types.

bash
grep -r --include="*.conf" --include="*.log" "error" /etc

This command searches recursively in both .conf and .log files.


Excluding Files and Directories During Recursive grep

Exclude specific files using --exclude

To prevent grep from searching inside specific files, use the --exclude option.

bash
grep -r --exclude="*.log" "error" /var/log

This command searches recursively but skips all .log files.

Exclude multiple file patterns

You can use --exclude multiple times to ignore different file types.

bash
grep -r --exclude="*.log" --exclude="*.gz" "error" /var/log

This excludes both .log and .gz files from the recursive search.

Exclude directories using --exclude-dir

If certain directories should be skipped during recursive search, use --exclude-dir.

bash
grep -r --exclude-dir=".git" "TODO" .

This searches recursively but ignores the .git directory.

Example excluding multiple directories:

bash
grep -r --exclude-dir="node_modules" --exclude-dir="cache" "config" .

Ignore binary files while searching

When searching large directories, binary files may produce unwanted matches. To skip them, use:

bash
grep -r --binary-files=without-match "error" /var

This prevents grep from scanning binary files.


Recursive grep for Multiple Patterns

Search multiple patterns using -e

You can search for multiple patterns at once using the -e option.

bash
grep -r -e "error" -e "failed" /var/log

This searches recursively for both error and failed patterns.

Search multiple patterns using regex

Multiple patterns can also be combined using a regex expression.

bash
grep -r "error\|failed" /var/log

This produces the same result as using multiple -e options.

Search patterns stored in a file

If you have many patterns, you can store them in a file and use the -f option.

Example pattern file patterns.txt:

bash
error
failed
timeout

Run recursive search using the file:

bash
grep -r -f patterns.txt /var/log

This searches recursively using all patterns listed in the file.


Find Files Containing Pattern Using Recursive grep

List only filenames with matches

To display only filenames that contain the matching pattern, use the -l option.

bash
grep -rl "error" /var/log

This lists only the files where the pattern appears.

List files without matches

To show files that do not contain the pattern, use -L.

bash
grep -rL "error" /var/log

This lists files where the pattern was not found.

To count how many matches exist in each file, use the -c option.

bash
grep -rc "error" /var/log

This prints the number of matches per file.


Advanced Recursive grep Examples

Search recursively and show surrounding lines

To display lines before and after a match, use the -C option.

bash
grep -r -C2 "error" /var/log

This shows two lines before and two lines after each match.

Search recursively and highlight matches

To highlight matched text in the output, use the --color option.

bash
grep -r --color "error" /var/log

This makes the matching pattern easier to identify in the results.

Search recursively and stop after first match

To stop searching a file after the first match is found, use -m.

bash
grep -r -m1 "error" /var/log

This speeds up searches when you only need the first occurrence.

Search recursively while ignoring permission errors

If certain directories have restricted permissions, grep may print errors. To suppress them, use the -s option.

bash
grep -rs "error" /

This performs recursive search while hiding permission denied messages.


By default, grep -r searches files recursively but does not follow symbolic links inside directories. To include files referenced through symbolic links, use the -R option.

bash
grep -R "error" /var/log

This command searches all files under /var/log and also follows any symbolic links found in the directory structure.

The difference between -r and -R is how symbolic links are handled.

OptionBehaviour
-rRecursively searches directories but ignores symbolic links unless specified directly
-RRecursively searches directories and follows symbolic links

Example using -r:

bash
grep -r "timeout" /etc

Example including symbolic links:

bash
grep -R "timeout" /etc

Use -R when your directory structure contains symbolic links pointing to other files or directories that should also be searched.

When to use --dereference-recursive

The long option --dereference-recursive behaves the same as -R.

bash
grep --dereference-recursive "error" /var/log

This option is useful when writing scripts where long-form arguments improve readability.


Combining grep Recursive with find Command

Using find and grep together

Although grep -r can search directories recursively, combining find with grep provides more control over which files are searched.

Example:

bash
find /etc -type f -name "*.conf" -exec grep "timeout" {} +

This command searches only .conf files under /etc and looks for the pattern timeout.

When find is better than recursive grep

find is useful when you need advanced filtering such as:

  • searching files based on modification time
  • limiting search depth
  • filtering specific file permissions
  • searching only large or small files

Example searching recently modified files:

bash
find /var/log -mtime -1 -type f -exec grep "error" {} +

This searches files modified within the last 24 hours.

Limiting search depth with find

The find command allows controlling how deep the search should go using -maxdepth.

Example:

bash
find /etc -maxdepth 2 -type f -exec grep "timeout" {} +

This searches files only within two directory levels under /etc.


Frequently Asked Questions

1. How do I run grep recursively in Linux?

You can search recursively using the -r or --recursive option. For example: grep -r 'pattern' /directory will search all files inside the directory and its subdirectories.

2. What is the difference between grep -r and grep -R?

The -r option searches directories recursively but ignores symbolic links unless specified directly, while -R follows symbolic links and searches the referenced files as well.

3. How do I search only specific file types with recursive grep?

You can use the --include option to limit the search to specific file types. For example: grep -r --include='*.conf' 'pattern' /etc.

4. How do I exclude directories when using recursive grep?

Use the --exclude-dir option to skip directories. For example: grep -r --exclude-dir='.git' 'pattern' .

5. How do I search multiple patterns using recursive grep?

You can use multiple -e options such as: grep -r -e 'error' -e 'failed' /var/log.

Summary

Recursive search is one of the most useful capabilities of the grep command when working with large directory structures. By using options such as -r or --recursive, you can search patterns across directories and sub-directories without manually specifying every file.

Additional options like --include, --exclude, --exclude-dir, and -R help refine recursive searches by filtering file types, skipping directories, or including symbolic links.

For more advanced filtering and control over file selection, grep can also be combined with the find command. Together these tools provide a powerful way to locate patterns inside large sets of files on Linux systems.


Further Reading

Deepak Prasad

Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels across development, DevOps, networking, and security, delivering robust and efficient solutions for diverse projects.