Skip to content
grep Command in Linux — 10 Practical Examples

grep Command in Linux — 10 Practical Examples

DodaTech Updated Jun 20, 2026 8 min read

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
  
Prerequisites: A Linux terminal. See Linux fundamentals if you’re new. These examples work on any distribution.

Syntax Overview

grep [options] pattern [file...]
OptionLong FormDescription
-i--ignore-caseCase-insensitive search
-r--recursiveSearch directories recursively
-v--invert-matchShow lines NOT matching the pattern
-c--countCount matching lines instead of showing them
-n--line-numberShow line numbers with matches
-H--with-filenamePrint filename for each match
-l--files-with-matchesList only filenames with matches
-E--extended-regexpExtended regular expressions
-A N--after-context=NShow N lines after match
-B N--before-context=NShow N lines before match
-C N--context=NShow 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 terminated

1. 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 down

2. 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 crashed

Note: “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 cases

4. 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 terminated

Wait — 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 crashed

5. Count Matches

Count how many ERROR lines exist:

grep -c "ERROR" server.log
3

6. Show Line Numbers

Find ERROR lines with their line numbers:

grep -n "ERROR" server.log
4:[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 down

7. 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 crashed

Find 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 3

8. 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 crashed

AND — 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 down

9. 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 terminated

Show 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 3

10. 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.gz

Find 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.log

Common 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.txt

2. 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 connection

FAQ

What does grep stand for?
grep stands for “global regular expression print” — it comes from the ed command g/re/p (globally search a regular expression and print).
How is grep different from find?
grep searches inside files for content patterns. find searches for files by name, type, size, or metadata. They’re often combined: find . -name "*.py" -exec grep "TODO" {} +.
Can grep search binary files?
Yes, but it shows “Binary file matches” by default. Use -a (–text) to treat binary files as text, or -I to ignore binary files entirely.
What’s the difference between grep, egrep, and fgrep?
egrep is equivalent to grep -E (extended regex), and fgrep is equivalent to grep -F (fixed strings, no regex). Modern grep supports both through flags.

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