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
-Ewhen using extended regex (+,?,{n},|, parens) — without it, you need to escape them with backslashes. - Searching huge files without paging: pipe into
lessinstead 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.