grep Cheat Sheet

Sidebar

Linux ยท grep Cheat Sheet

Searching text, at a glance. The options were run on GNU grep 3.0 (the one on Linux and in Git Bash). For the regex syntax itself, see Learning Regular Expressions; for editing what you find, SED — A Course for Beginners and AWK.

Basics

grep PAT filePrint lines that match
grep PAT f1 f2Several files (output gets the file name)
cmd | grep PATFilter another command's output
-iIgnore case
-vInvert: lines that do NOT match
-wWhole words only
-xWhole line must match
-FFixed string: no regex (a . is just a dot)
-e A -e BSeveral patterns (A or B)
-f filePatterns from a file, one per line

Output Control

-nShow line numbers
-cCount matching lines (not matches)
-oPrint only the matching part
-l / -LOnly names of files with / without a match
-m NStop after N matching lines
-H / -hAlways / never show the file name
-bByte offset of each match
-qQuiet: print nothing, just set the exit code
-sHide errors about missing or unreadable files
--color=autoHighlight the match

Context

-A NN lines After each match
-B NN lines Before each match
-C NN lines of Context either side
--Groups of matches are separated by a -- line
--no-group-separatorLeave that separator out

Files & Folders

-rRecurse into folders (no path: current folder)
-RAs -r, but also follows symbolic links
--include='*.py'Only search files matching this name
--exclude='*.log'Skip files matching this name
--exclude-dir=.gitSkip a folder (repeat the option for more)
-ISkip binary files
-aTreat binary files as text
-ZEnd file names with a NUL (for xargs -0)

Basic Regex (default)

^ $Start / end of line
.Any one character
*Zero or more of the last item
[abc] [^abc]One of / none of these characters
[a-z]A range
\< \> \bStart / end of a word / either edge
\(ab\) \1Group, and a back-reference to it
\{2,4\}Between 2 and 4 of the last item
\+ \? \|One or more / optional / or (GNU grep)

Extended Regex (-E)

+ ? |One or more / optional / or, no backslashes
(ab|cd)Group with alternatives
{2,4}Between 2 and 4
-E '^(error|warn)'Lines starting with either word
-E 'colou?r'color or colour
-E '[0-9]{3}-[0-9]{4}'A phone-style number

Character Classes

[[:digit:]]0-9
[[:alpha:]]Letters
[[:alnum:]]Letters and digits
[[:upper:]] [[:lower:]]Upper / lower case letters
[[:space:]]Space, tab, newline
[[:punct:]]Punctuation

Perl Regex (-P, GNU only)

\d \s \wDigit / space / word character
*? +?Lazy: as little as possible
(?=x) (?!x)Followed by / not followed by x
(?<=x) (?<!x)Preceded by / not preceded by x
\KForget what was matched so far
-oP 'id=\K\d+'Print just the number after id=

Pipelines & Recipes

ps aux | grep [n]ginxFind a process without matching grep itself
grep -rn TODO --include='*.js' .Find TODOs in JavaScript files
grep -rIlZ PAT . | xargs -0 sed -i ...Replace across files: add --exclude-dir=.git, or -r edits .git too
grep -Fxf a bLines of file b that are also in file a
grep -vFxf a bLines of file b that are NOT in file a
grep -c '' fileCount all lines in a file
grep -o PAT f | sort | uniq -cCount how often each match occurs
grep -v '^#' f | grep -v '^$'Hide comments and blank lines

Exit Status

0At least one line matched
1No lines matched (not an error)
2A real error (bad file, bad pattern)
if grep -q PAT f; then ...Test for a match in a script
The #1 trap: quote your pattern
Always put the pattern in single quotes. Unquoted, the shell gets there first: grep error|warn log pipes grep into a command called warn, and * or $ are expanded before grep ever sees them. And in basic regex a bare |, +, ?, ( or { is just a literal character: add -E if you meant it as an operator. Also, -P is not in every grep (macOS/BSD grep often lacks it).