Introduction
When performing text searches in Linux or Unix environments, grep is an indispensable command.
Especially when dealing with multiple directories or a large number of files, using recursive search lets you efficiently find the target string.
However, there are many types of options, and it's not uncommon for beginners to get confused about how to use them.
This article explains everything from the basics to more advanced usage.
Reference: GNU grep
Basic Syntax for grep Recursive Search
Create Files
mkdir -p sample/dir1 sample/dir2
Create Files
echo "INFO Start" > sample/file1.txt
Create Files
echo "ERROR Database connection failed" > sample/dir1/file2.txt
Create Files
echo "WARNING Disk usage high" > sample/dir2/file3.log
Command to Run
grep -r "ERROR" sample
Result
sample/dir1/file2.txt:ERROR Database connection failed
How It Works
| Item | Description |
|---|---|
| grep | Command that searches text for a specified string |
| -r | Option to recursively search through a directory |
| "ERROR" | The string to search for |
| sample/ | Starting directory for the search |
| Search results | Displayed in the format filename:matched line |
Explanation
For grep's recursive search, the -r option is used to search all files under the specified directory.
This is a basic feature commonly used for log analysis and configuration file investigation.
How to Target the Current Directory with grep Recursive Search
Create Files
mkdir -p logs
Create Files
cat << 'EOT' > input.txt
sample text
error message
target string
EOT
Create Files
cat << 'EOT' > logs/error.log
error found
target string in log
EOT
Command to Run
grep -r "error" .
Result
./input.txt:error message
./logs/error.log:error found
Command to Run
grep -r "target" .
Result
./input.txt:target string
./logs/error.log:target string in log
How It Works
| Item | Description |
|---|---|
| Command | grep -r "search string" . |
| -r | Recursively searches through a directory |
| . | Targets the current directory for the search |
| Search target | All files and subdirectories under the current directory |
| Output format | filename:matched line |
Explanation
grep -r searches for a string while recursively traversing the specified directory.
Specifying . as in grep -r "error" . makes the entire current directory the search target.
How to Display File Names with grep Recursive Search
Create Files
cat << 'EOF' > input.txt
sample text
target keyword
subdir target keyword
EOF
Create Files
mkdir -p logs
Create Files
cp input.txt logs/app.log
Command to Run
grep -r "target" .
Result
./input.txt:target keyword
./input.txt:subdir target keyword
./logs/app.log:target keyword
./logs/app.log:subdir target keyword
Command to Run
grep -rn "target" .
Result
./input.txt:2:target keyword
./input.txt:3:subdir target keyword
./logs/app.log:2:target keyword
./logs/app.log:3:subdir target keyword
How It Works
| Item | Description |
|---|---|
| grep | Command that searches text |
| -r | Recursively searches through a directory |
| -n | Displays the line number of matches |
| File name display | The matched file name is automatically shown during a recursive search |
| Search target | Specifying . searches under the current directory |
Explanation
Using grep -r lets you search recursively, including subdirectories.
Matched lines are displayed in the format filename:content, so you can immediately see which file they're in.
How to Display Line Numbers with grep Recursive Search
Create Files
cat << 'EOF' > input.txt
sample.txt:apple
logs/app.log:apple
logs/error.log:banana
src/main.txt:apple
EOF
Create Files
mkdir -p logs src
Create Files
awk -F: '$1=="sample.txt"{print $2}' input.txt > sample.txt
awk -F: '$1=="logs/app.log"{print $2}' input.txt > logs/app.log
awk -F: '$1=="logs/error.log"{print $2}' input.txt > logs/error.log
awk -F: '$1=="src/main.txt"{print $2}' input.txt > src/main.txt
Command to Run
grep -rn "apple" .
Result
./logs/app.log:1:apple
./sample.txt:1:apple
./src/main.txt:1:apple
How It Works
| Option | How It Works |
|---|---|
| -r | Recursively searches through a directory |
| -n | Displays the line number of matched lines |
| "apple" | Specifies the string to search for |
| . | Targets the current directory for the search |
Explanation
Using grep -rn lets you search recursively, including subdirectories, while also displaying line numbers.
This is useful when you want to quickly pinpoint the location of a target string across multiple files.
How to Make grep Recursive Search Case-Insensitive
Create Files
cat << 'EOF' > input.txt
Apple
apple
Banana
banana
EOF
Command to Run
grep -ri "apple" .
Result
./input.txt:Apple
./input.txt:apple
How It Works
| Item | Description |
|---|---|
| grep | Command that performs a text search |
| -r | Recursively searches through a directory |
| -i | Searches without distinguishing between uppercase and lowercase |
| "apple" | The string to search for |
| . | Targets everything under the current directory |
Explanation
grep's -r option lets you recursively search through a directory.
Combining it with -i lets you search for matching strings regardless of uppercase or lowercase.
How to Search for Multiple Keywords with grep Recursive Search
Create Files
mkdir -p logs src
Create Files
cat << 'EOL' > logs/app.log
application started
error occurred
warning message
EOL
Create Files
cat << 'EOL' > src/main.txt
sample data
sample error data
warning and error
EOL
Command to Run
grep -rE 'error|warning' logs src
Result
logs/app.log:error occurred
logs/app.log:warning message
src/main.txt:sample error data
src/main.txt:warning and error
Command to Run
grep -r -e 'error' -e 'warning' logs src
Result
logs/app.log:error occurred
logs/app.log:warning message
src/main.txt:sample error data
src/main.txt:warning and error
How It Works
| Item | Description |
|---|---|
| grep | Command that searches file contents |
| -r | Recursively searches under the specified directory |
| -E | Enables extended regular expressions |
| error|warning | Searches for multiple keywords with an OR condition |
| -e | Specifies multiple search patterns |
| grep -rE 'error|warning' logs src | Recursive search for multiple keywords using a regular expression |
| grep -r -e 'error' -e 'warning' logs src | Recursive search for multiple keywords using -e |
Explanation
grep's recursive search lets you target files under a directory by using -r.
You can search for multiple keywords using the OR condition with -E or by specifying multiple patterns with -e.
How to Use Regular Expressions with grep Recursive Search
Create Files
mkdir -p logs src docs config
Create Files
cat << 'EOT' > src/main.py
import os
print("hello")
EOT
Create Files
cat << 'EOT' > src/utils.py
def test():
pass
EOT
Create Files
cat << 'EOT' > logs/app.log
ERROR Connection failed
EOT
Create Files
cat << 'EOT' > logs/debug.log
INFO Debug message
EOT
Create Files
cat << 'EOT' > docs/readme.md
grep recursive search sample
EOT
Create Files
cat << 'EOT' > config/settings.conf
max_retry=3
EOT
Command to Run
grep -Er 'ERROR|max_retry=[0-9]+' logs config
Result
logs/app.log:ERROR Connection failed
config/settings.conf:max_retry=3
Command to Run
grep -Er 'def|import' src
Result
src/utils.py:def test():
src/main.py:import os
Command to Run
grep -Eri 'grep.*search' docs
Result
docs/readme.md:grep recursive search sample
Command to Run
grep -Er '^(ERROR|INFO)' logs
Result
logs/debug.log:INFO Debug message
logs/app.log:ERROR Connection failed
How It Works
| Item | Description |
|---|---|
| grep | Command that searches file contents |
| -r | Recursively searches through a directory |
| -E | Enables extended regular expressions |
| -i | Ignores case |
| ERROR|max_retry=[0-9]+ | Combination of an OR condition and a numeric pattern |
| def|import | Searches for function definitions or import statements in Python source |
| grep.*search | A pattern with any string between grep and search |
| ^(ERROR|INFO) | Searches for lines beginning with ERROR or INFO |
Explanation
Using grep -r lets you recursively search under multiple directories.
Combining it with -E lets you use regular expressions such as OR conditions and repetition, making grep's recursive search more flexible.
How to Target Only Specific File Extensions with grep Recursive Search
Create Files
mkdir -p logs archive
Create Files
cat << 'EOF' > logs/app.log
INFO: Application started
ERROR: Database connection failed
EOF
Create Files
cat << 'EOF' > logs/system.txt
ERROR: Disk full
EOF
Create Files
cat << 'EOF' > archive/old.log
ERROR: Old log message
EOF
Command to Run
grep -r --include="*.log" "ERROR" .
Result
./archive/old.log:ERROR: Old log message
./logs/app.log:ERROR: Database connection failed
Command to Run
grep -rn --include="*.log" "ERROR" .
Result
./archive/old.log:1:ERROR: Old log message
./logs/app.log:2:ERROR: Database connection failed
How It Works
| Option | Description |
|---|---|
| grep | Text search command |
| -r | Recursively searches through a directory |
| -n | Displays line numbers |
| --include="*.log" | Targets only files with the .log extension |
| "ERROR" | The string to search for |
| . | Targets everything under the current directory |
Explanation
Using grep -r lets you recursively search through a directory.
Combining it with --include="*.log" lets you efficiently search only files with a specific extension.
How to Exclude a Specific Directory with grep Recursive Search
Create Files
mkdir -p logs/archive src
Create Files
cat << 'EOL' > logs/app.log
INFO Application started
ERROR Database connection failed
EOL
Create Files
cat << 'EOL' > logs/archive/old.log
ERROR Legacy system error
EOL
Create Files
cat << 'EOL' > src/main.py
print("hello")
EOL
Command to Run
grep -r --exclude-dir=archive "ERROR" logs src
Result
logs/app.log:ERROR Database connection failed
Command to Run
grep -r "ERROR" logs src
Result
logs/archive/old.log:ERROR Legacy system error
logs/app.log:ERROR Database connection failed
How It Works
| Item | Description |
|---|---|
| grep -r | Recursively searches under the specified directory |
| --exclude-dir=archive | Excludes the archive directory from the search target |
| "ERROR" | Specifies the string to search for |
| logs src | Specifies the directories to search |
Explanation
grep -r can recursively search through a directory.
Using --exclude-dir lets you search efficiently while excluding unneeded directories such as archived logs.
How to Display Lines Before and After a Match with grep Recursive Search
Create Files
mkdir -p logs
Create Files
cat << 'EOF' > logs/app.log
INFO Application started
ERROR Database connection failed
INFO Retrying connection
INFO Retry succeeded
EOF
Create Files
cat << 'EOF' > logs/api.log
INFO Request received
WARN Slow response detected
ERROR Timeout occurred
INFO Request finished
EOF
Command to Run
grep -r -B 1 -A 1 "ERROR" logs
Result
logs/api.log-WARN Slow response detected
logs/api.log:ERROR Timeout occurred
logs/api.log-INFO Request finished
--
logs/app.log-INFO Application started
logs/app.log:ERROR Database connection failed
logs/app.log-INFO Retrying connection
How It Works
| Option | Description |
|---|---|
| grep | Command that searches text |
| -r | Recursively searches under the specified directory |
| -B 1 | Displays the 1 line before each match |
| -A 1 | Displays the 1 line after each match |
| "ERROR" | The string to search for |
| logs | The directory to recursively search |
Explanation
Using grep -r lets you recursively search all files under the logs directory.
Specifying -B and -A lets you also check the logs before and after the matched line, which is helpful for understanding the situation when an error occurs.
How to Tally Search Result Counts with grep Recursive Search
Create Files
mkdir -p logs
Create Files
cat << 'LOG1' > logs/app.log
ERROR Database connection failed
ERROR Timeout occurred
INFO Application started
LOG1
Create Files
cat << 'LOG2' > logs/api.log
ERROR Invalid request
ERROR Authentication failed
ERROR Timeout occurred
LOG2
Create Files
cat << 'LOG3' > logs/system.log
INFO System started
ERROR Disk full
LOG3
Command to Run
grep -r "ERROR" logs
Result
logs/api.log:ERROR Invalid request
logs/api.log:ERROR Authentication failed
logs/api.log:ERROR Timeout occurred
logs/system.log:ERROR Disk full
logs/app.log:ERROR Database connection failed
logs/app.log:ERROR Timeout occurred
Command to Run
grep -r "ERROR" logs | wc -l
Result
6
How It Works
| Item | Description |
|---|---|
| mkdir -p logs | Creates a directory for storing logs |
| grep -r | Recursively searches under the specified directory |
| grep -r "ERROR" logs | Searches all files under logs for ERROR |
| wc -l | Counts the number of lines in the search results |
| Tally result | Displays the number of matches for ERROR |
Explanation
Using grep -r lets you recursively search multiple files under a directory.
Piping the search results to wc -l lets you easily tally the number of matches.
How to Combine grep Recursive Search with the find Command
Create Files
mkdir -p testdir/src testdir/logs testdir/docs
Create Files
echo "sample text
error message
debug log" > testdir/sample.txt
Create Files
echo "error found" > testdir/src/main.txt
Create Files
echo "error occurred" > testdir/logs/app.log
Create Files
echo "grep recursive search" > testdir/docs/readme.md
Command to Run
grep -r "error" testdir
Result
testdir/logs/app.log:error occurred
testdir/sample.txt:error message
testdir/src/main.txt:error found
Command to Run
find testdir -type f -exec grep -H "error" {} \;
Result
testdir/logs/app.log:error occurred
testdir/sample.txt:error message
testdir/src/main.txt:error found
How It Works
| Item | Description |
|---|---|
| grep -r | Recursively searches under the specified directory |
| find | Searches for files matching certain conditions |
| -type f | Targets only regular files |
| -exec | Runs a command against find's search results |
| grep -H | Displays the matched line along with the file name |
| Benefit of combining them | You can run grep while applying conditions such as file type or modification date |
Explanation
grep -r lets you easily perform a recursive search through a directory.
Combining it with find lets you flexibly narrow down target files while searching, which is why this combination is also commonly used in real-world operations.
Tips for Speeding Up grep Recursive Search
Create Files
mkdir -p logs src vendor
Create Files
cat << 'LOG' > logs/app.log
Application started
LOG
Create Files
cat << 'LOG' > logs/error.log
Error: connection timeout
LOG
Create Files
cat << 'PY' > src/main.py
print("main application")
PY
Create Files
cat << 'PY' > src/utils.py
def helper():
pass
PY
Create Files
cat << 'JS' > vendor/lib.js
console.log("library");
JS
Create Files
cat << 'JS' > vendor/jquery.js
console.log("jquery");
JS
Command to Run
grep -r --include="*.py" "main" .
Result
./src/main.py:print("main application")
Command to Run
grep -r --exclude-dir=vendor "Error" .
Result
./logs/error.log:Error: connection timeout
Command to Run
grep -r --exclude-dir=vendor "Application" .
Result
./logs/app.log:Application started
How It Works
| Item | How It Works | Reason It's Faster |
|---|---|---|
| -r | Recursively searches through a directory | No need to manually specify each file |
| --include="*.py" | Searches only the specified extension | Reduces the reading of unneeded files |
| --exclude-dir=vendor | Excludes the specified directory from the search target | Avoids scanning large numbers of library files |
| Narrowing the search target | Explores only the needed files | Reduces disk I/O and processing time |
Explanation
grep's recursive search is convenient, but limiting the search target can greatly improve processing speed.
This is especially effective when excluding large directories such as vendor or node_modules.
Key Points Summary for grep Recursive Search
grep's recursive search is a convenient feature that lets you search all the files under a directory at once.
Once you understand the basic syntax, you can improve search efficiency by combining it with features such as file name display, line number display, and the use of regular expressions.
By mastering grep's recursive search, you can streamline everyday tasks like log analysis and source code investigation.
