grep Command in Linux — 10 Practical Examples
grep is the Linux command-line tool for searching plain-text data using patterns and regular expressions. It reads files or standard input and prints every line that matches a given pattern — making it essential for log analysis, code searching, and data filtering.
What You’ll Learn
By the end of this tutorial, you’ll know how to use grep for basic searches, case-insensitive matching, recursive directory searches, invert matching, counting matches, showing line numbers, regex patterns, combining OR/AND conditions, displaying context lines, and recursive search with filenames.
Why grep Matters
Every system administrator, developer, and security analyst searches through files daily — log files, source code, configuration files, and output from other commands. grep is the fastest way to find exactly what you need. Durga Antivirus Pro uses grep-style pattern matching to scan file signatures, and DodaZIP uses it to filter log entries during compression workflows.
grep Learning Path
flowchart LR
A[Linux Basics] --> B[Essential Commands]
B --> C[grep Command<br/>You are here]
C --> D[sed Command]
D --> E[awk Command]
style C fill:#f90,color:#fff
Syntax Overview
grep [options] pattern [file...]| Option | Long Form | Description |
|---|---|---|
-i | --ignore-case | Case-insensitive search |
-r | --recursive | Search directories recursively |
-v | --invert-match | Show lines NOT matching the pattern |
-c | --count | Count matching lines instead of showing them |
-n | --line-number | Show line numbers with matches |
-H | --with-filename | Print filename for each match |
-l | --files-with-matches | List only filenames with matches |
-E | --extended-regexp | Extended regular expressions |
-A N | --after-context=N | Show N lines after match |
-B N | --before-context=N | Show N lines before match |
-C N | --context=N | Show N lines before and after |
10 Practical Examples
We’ll use a sample log file server.log for most examples:
cat server.log[2026-06-20 10:00:01] INFO Server started on port 8080
[2026-06-20 10:00:05] DEBUG Loading configuration from /etc/app/config.yml
[2026-06-20 10:00:07] WARN Disk usage at 85% — consider cleanup
[2026-06-20 10:01:12] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:01:15] INFO Retry attempt 1 of 3
[2026-06-20 10:01:20] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:01:25] INFO Retry attempt 2 of 3
[2026-06-20 10:02:00] ERROR Database connection failed — shutting down
[2026-06-20 10:02:05] FATAL Application crashed
[2026-06-20 10:02:10] INFO Server process terminated1. Basic Search
Search for lines containing “ERROR”:
grep "ERROR" server.log[2026-06-20 10:01:12] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:01:20] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:02:00] ERROR Database connection failed — shutting down2. Case-Insensitive Search
Search for “error” regardless of case:
grep -i "error" server.log[2026-06-20 10:00:01] INFO Server started on port 8080
[2026-06-20 10:01:12] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:01:20] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:02:00] ERROR Database connection failed — shutting down
[2026-06-20 10:02:05] FATAL Application crashedNote: “FATAL” matched because it contains “error” in lowercase.
3. Recursive Search
Search for “TODO” across all files in a project:
grep -r "TODO" /home/projects/myapp//home/projects/myapp/src/main.py:15: # TODO: Add input validation
/home/projects/myapp/src/utils.py:42: # TODO: Refactor this function
/home/projects/myapp/tests/test_main.py:8: # TODO: Write more test cases4. Invert Match
Show all lines that do NOT contain “INFO”:
grep -v "INFO" server.log[2026-06-20 10:00:05] DEBUG Loading configuration from /etc/app/config.yml
[2026-06-20 10:00:07] WARN Disk usage at 85% — consider cleanup
[2026-06-20 10:01:12] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:01:20] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:02:00] ERROR Database connection failed — shutting down
[2026-06-20 10:02:05] FATAL Application crashed
[2026-06-20 10:02:10] INFO Server process terminatedWait — the last line also contains “INFO”. Let me remove empty lines too:
grep -v "INFO" server.log | grep -v "^$"[2026-06-20 10:00:05] DEBUG Loading configuration from /etc/app/config.yml
[2026-06-20 10:00:07] WARN Disk usage at 85% — consider cleanup
[2026-06-20 10:01:12] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:01:20] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:02:00] ERROR Database connection failed — shutting down
[2026-06-20 10:02:05] FATAL Application crashed5. Count Matches
Count how many ERROR lines exist:
grep -c "ERROR" server.log36. Show Line Numbers
Find ERROR lines with their line numbers:
grep -n "ERROR" server.log4:[2026-06-20 10:01:12] ERROR Connection timeout to database (host: db01)
6:[2026-06-20 10:01:20] ERROR Connection timeout to database (host: db01)
8:[2026-06-20 10:02:00] ERROR Database connection failed — shutting down7. Regex Patterns
Find lines with WARN or ERROR using extended regex:
grep -E "WARN|ERROR|FATAL" server.log[2026-06-20 10:00:07] WARN Disk usage at 85% — consider cleanup
[2026-06-20 10:01:12] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:01:20] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:02:00] ERROR Database connection failed — shutting down
[2026-06-20 10:02:05] FATAL Application crashedFind timestamps with minutes 01 (any second):
grep -E "10:01:[0-9]{2}" server.log[2026-06-20 10:01:12] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:01:15] INFO Retry attempt 1 of 3
[2026-06-20 10:01:20] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:01:25] INFO Retry attempt 2 of 38. OR / AND with Multiple Patterns
OR — lines matching either pattern:
grep -E "WARN|FATAL" server.log[2026-06-20 10:00:07] WARN Disk usage at 85% — consider cleanup
[2026-06-20 10:02:05] FATAL Application crashedAND — lines matching both patterns (pipe through two greps):
grep "ERROR" server.log | grep -i "database"[2026-06-20 10:01:12] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:01:20] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:02:00] ERROR Database connection failed — shutting down9. Context Lines
Show 1 line before and after each ERROR match:
grep -C 1 "FATAL" server.log[2026-06-20 10:02:00] ERROR Database connection failed — shutting down
[2026-06-20 10:02:05] FATAL Application crashed
[2026-06-20 10:02:10] INFO Server process terminatedShow 2 lines after each match:
grep -A 2 "WARN" server.log[2026-06-20 10:00:07] WARN Disk usage at 85% — consider cleanup
[2026-06-20 10:01:12] ERROR Connection timeout to database (host: db01)
[2026-06-20 10:01:15] INFO Retry attempt 1 of 310. Recursive Search with Filenames
Search for “function” across a project, always showing filenames:
grep -rH "function" /home/projects/myapp//home/projects/myapp/src/main.py:10: def main():
/home/projects/myapp/src/utils.py:5: def parse_config():
/home/projects/myapp/src/utils.py:20: def validate_input():Common Use Cases
Search Compressed Logs
zgrep "ERROR" /var/log/syslog.1.gzFind Files Containing a Pattern
grep -rl "main(" /home/projects/Filter Output of Another Command
ps aux | grep "python"Search with Word Boundaries
grep -w "error" file.logCommon Mistakes
1. Forgetting Quotes Around the Pattern
# Wrong — searches for "hello" in file "world" then file "file.txt"
grep hello world file.txt
# Right
grep "hello world" file.txt2. Confusing -r and -R
-r follows symlinks only if they point to directories; -R follows all symlinks. Use -R to be thorough.
3. Using Basic Regex When Extended Is Needed
+, ?, |, ( and ) have special meaning in extended regex but are literal in basic regex. Use -E to enable extended mode.
4. Not Escaping Special Characters
Searching for 10.00.00.01 matches any character between the numbers. Escape dots: grep "10\.00\.00\.01".
Practice Questions
1. How do you recursively search all .py files for “import os”?
grep -r --include="*.py" "import os" /home/projects/
2. What does grep -c "error" file.log count?
It counts the number of lines containing “error” (case-sensitive), not the number of occurrences per line.
3. How do you find lines that do NOT match a pattern?
Use the -v flag: grep -v "DEBUG" server.log shows everything except lines with “DEBUG”.
4. How do you show exactly 3 lines after each match?
grep -A 3 "pattern" file.txt
5. Challenge: Write a one-liner that counts how many unique ERROR types appear in a log file.
grep "ERROR" server.log | awk -F'ERROR' '{print $2}' | awk '{print $1}' | sort -u | wc -l
Mini Project: Error Summary Report
Create a script that summarizes errors from any log file:
#!/bin/bash
# error_summary.sh — Summarize errors from a log file
# Usage: ./error_summary.sh /var/log/app.log
LOG_FILE="${1:-server.log}"
if [ ! -f "$LOG_FILE" ]; then
echo "Error: File not found: $LOG_FILE"
exit 1
fi
echo "=== Error Summary ==="
echo "File: $LOG_FILE"
echo ""
echo "Total ERROR lines: $(grep -c "ERROR" "$LOG_FILE")"
echo ""
echo "=== Error Categories ==="
grep -oP 'ERROR \K[^—]*' "$LOG_FILE" | sort | uniq -c | sort -rn
echo ""
echo "=== Error Timeline ==="
grep "ERROR" "$LOG_FILE" | awk '{print $1, $2, $3, $4}'Expected output:
=== Error Summary ===
File: server.log
Total ERROR lines: 3
=== Error Categories ===
2 Connection timeout to database (host: db01)
1 Database connection failed
=== Error Timeline ===
[2026-06-20 10:01:12] ERROR Connection timeout
[2026-06-20 10:01:20] ERROR Connection timeout
[2026-06-20 10:02:00] ERROR Database connectionFAQ
What’s Next
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro