grep: Search Text Like a Pro

grep finds patterns in text. It is the single most-used Unix tool after ls. You will use it for log debugging, code search, config inspection, and threading commands together with pipes. Learn its 10 most useful flags and you instantly become faster at the terminal.

Basic usage

grep "pattern" file.txt              # find lines containing "pattern"
grep "pattern" file1 file2           # search multiple files
grep "pattern" *.log                 # glob expansion
cat file.txt | grep "pattern"        # via pipe

The flags you’ll actually use

grep -i "Error" log.txt        # case-insensitive
grep -v "DEBUG" log.txt        # invert: show lines NOT matching
grep -n "pattern" file         # show line numbers
grep -c "ERROR" log.txt        # count matches (not lines)
grep -l "pattern" *.txt        # list FILES that contain match
grep -L "pattern" *.txt        # list files that DO NOT match
grep -r "TODO" .               # recursive (search subdirectories)
grep -R "TODO" .               # like -r but follow symlinks
grep -w "user" file            # match whole words only
grep -A 3 "ERROR" log.txt      # show 3 lines AFTER each match
grep -B 3 "ERROR" log.txt      # show 3 lines BEFORE each match
grep -C 3 "ERROR" log.txt      # 3 lines of context (both)
grep --color=auto              # highlight matches in color

Regex with grep

By default, grep uses basic regular expressions (BRE). Use -E for extended regex (ERE), or -P for Perl regex (where available).

# Anchors
grep "^Error" log.txt              # lines STARTING with Error
grep "done$" log.txt               # lines ENDING with done
grep "^$" file                     # blank lines
grep -v "^$" file                  # NON-blank lines

# Character classes
grep "[0-9]" file                  # any digit
grep "[A-Z][a-z]*" file            # capitalized word
grep "[^a-z]" file                 # NOT lowercase letter

# Extended regex (use -E)
grep -E "Error|Warning" log.txt    # OR
grep -E "[0-9]{3}-[0-9]{4}" file   # phone-ish pattern
grep -E "(red|blue|green)" file    # alternation

# Match an IP address
grep -E "([0-9]{1,3}.){3}[0-9]{1,3}" log.txt

Real-world one-liners

# All lines that contain BOTH "user" and "login" (any order)
grep "user" file | grep "login"

# Top 5 most frequent IPs in nginx access log
grep -oE "^[0-9.]+" access.log | sort | uniq -c | sort -rn | head -5

# Find all files that contain a TODO
grep -rln "TODO" ~/projects/

# Search inside zip without extracting
zgrep "error" my.log.gz

# Search recursively but skip hidden directories
grep -r --exclude-dir='.*' "TODO" .

# Search only specific file types
grep -r --include="*.py" "import os" .

The faster grep: ripgrep (rg)

If you do a lot of code search, install ripgrep. It is grep + smart defaults (gitignore-aware, recursive by default, parallel, fast).

sudo apt install ripgrep    # debian/ubuntu
sudo dnf install ripgrep    # fedora
brew install ripgrep        # mac

rg "TODO"                   # recursive, fast, color, gitignore-aware
rg -t py "import"           # only Python files
rg -i "error"               # case-insensitive

Common mistakes

  • Using single quotes when you want shell expansion, or double quotes when you want literal regex. Default to single quotes for grep patterns: grep '$VAR' file.
  • Forgetting -E when using extended regex (+, ?, {n}, |, parens) — without it, you need to escape them with backslashes.
  • Searching huge files without paging: pipe into less instead of letting your terminal scroll forever.

What to learn next

grep finds. sed transforms. Together they handle most text problems on Linux. sed is up next.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *