Cheat Sheet

grep Cheat Sheet

grep prints the lines that match a pattern, from files or from whatever you pipe into it. This sheet covers the everyday flags, recursive search, the regex syntax, context lines, and what to use instead on Windows.

Last updated September 5, 2026

The Basics

CommandWhat it does
Print lines containing error
Case insensitive (matches Error, ERROR)
Show line numbers
Invert: lines that do NOT match
Count matching lines instead of printing them
Match whole words only (skips passport)
Match whole lines only
Print only the matched text, not the whole line
Stop after the first match
List files that match, not the lines
List files that do NOT match
Fixed string: treat the pattern literally, no regex
Silent; exit code only (for in scripts)

counts matching lines, not occurrences. For total occurrences use .

CommandWhat it does
Search every file under the current directory
Recursive with file name and line number
Recursive, case insensitive
Just the file names (feeds nicely into xargs)
Only search .py files
Skip minified files
Skip a directory
Skip several directories
Like -r, but also follows symlinks

Multiple Patterns

CommandWhat it does
OR: match either pattern
OR with extended regex
Read patterns from a file, one per line
AND: lines containing both
Match one, exclude another
Exclude several patterns
Count lines matching either

Regex

grep's default dialect is basic regex (BRE). Add for extended regex (ERE), where , , , and work without backslashes. works on every grep, including macOS.

PatternMatches
Any single character
Zero or more of the previous item
error at the start of the line
error at the end of the line
Empty lines
Any one of these characters
Any character that is not a digit
Character ranges
, , POSIX classes (portable stand-ins for \d, \s)
A literal dot (escape to match them literally)
Word boundaries (same idea as -w)

With :

PatternMatches
One or more: gogle, google, gooogle
Optional: color and colour
Alternation
Grouping: ab, abab
Repetition counts (start of an IP address)

unlocks Perl regex (, , lookaheads) but only exists in GNU grep. The grep on macOS and BSD does not have it: use with POSIX classes, or and call .

Context Lines

CommandWhat it does
Show 3 lines After each match
Show 3 lines Before each match
3 lines of Context on both sides
Context plus line numbers

Groups of matches are separated by a line. Nearby matches merge into one block.

Pipes and xargs

grep is at its best at the end of a pipe. See the awk cheat sheet for what usually comes after it.

CommandWhat it does
Find a running process
Same, without grep matching its own process line
Search your shell history
Kernel messages about USB
Which proxy variables are set
Which log files contain error
Find files, then edit them (see the sed cheat sheet)
Safe with spaces in file names

grep on Windows

Windows has no grep built in, but both shells have an equivalent.

CommandWhat it does
cmd: basic search
cmd: case insensitive, recursive (roughly )
cmd: invert, like
cmd: regex, in findstr's own limited dialect
PowerShell: the real grep equivalent, full regex
PowerShell: grep is case sensitive by default, Select-String is not
PowerShell: recursive search
PowerShell: sls is the short alias

Git Bash and WSL both ship genuine GNU grep, so works there unchanged.

Gotchas

  • is GNU-only. On macOS, fails with "invalid option"; use or install GNU grep (, then ).
  • Always quote the pattern. Unquoted, the shell expands and against your files before grep ever sees them.
  • grep exits 1 when nothing matches. In a script with that kills the script; append when no-match is fine.
  • In basic regex, and are literal characters. matches the literal text go+gle; you want .
  • "Binary file matches" means the file has non-text bytes. forces it to be treated as text.
  • grep finds lines, sed edits them, and awk works on columns. The three cover most text jobs between them.

grep Cheat Sheet FAQ

How do I grep for multiple patterns at once?
For OR, either repeat -e (grep -e error -e warn file.log) or use extended regex: grep -E 'error|warn' file.log. With many patterns, put them one per line in a file and use grep -f patterns.txt. For AND, chain greps: grep error file.log | grep nginx keeps lines containing both. To exclude several patterns, combine -v with -E: grep -v -E 'debug|trace'.
How do I exclude a directory from a recursive grep?
Use --exclude-dir: grep -r "text" . --exclude-dir=node_modules. Repeat it for more directories or brace-expand: --exclude-dir={node_modules,.git,dist}. The name is matched against each directory's basename, not its path. --exclude="*.min.js" does the same for files, and --include="*.py" flips it around so only matching files are searched.
What is the difference between grep -E and grep -P?
-E turns on extended regex (ERE), where +, ?, |, () and {} work without backslashes; it is POSIX and works everywhere, including macOS. -P turns on Perl-compatible regex (PCRE), which adds \d, \s, \w, lookaheads and lazy quantifiers, but it is a GNU extension: the BSD grep that ships with macOS does not have it. On a Mac, rewrite \d as [0-9] with -E, or install GNU grep with brew install grep and call ggrep -P.
How do I grep for an exact match?
Depends what exact means. grep -w port matches port as a whole word, so it skips passport and portable. grep -x "exact line" matches only lines that are entirely that text. grep -F 'a.b[1]' treats the pattern as a literal string, so regex characters like dots and brackets lose their meaning. -w and -F combine when you need both.
Does grep work on Windows?
Not out of the box. cmd has findstr (findstr /S /I "error" *.log is roughly grep -ri), which covers basic cases but has a limited regex dialect. PowerShell's Select-String is much closer to real grep and supports full .NET regex. If you have Git for Windows or WSL installed, you already have genuine GNU grep in Git Bash or the WSL shell.

Related cheat sheets