grep — quick reference
Pattern matching
Control how grep interprets the search text.
| When to use | Command |
|---|---|
| Search for a literal string in one file | grep 'ERROR' app.log |
| Case-insensitive match | grep -i error app.log |
| Match whole words only | grep -w log words.txt |
| Extended regex (alternation, grouping) | grep -E 'error|warning' app.log |
| Fixed string — no regex metacharacters | grep -F 'rate.limit' app.log |
| Multiple patterns in one run | grep -e error -e warning app.log |
| Patterns listed in a file | grep -f patterns.txt app.log |
Output control
Shape what grep prints.
| When to use | Command |
|---|---|
| Show line numbers | grep -n error app.log |
| Count matching lines | grep -c error app.log |
| Print only the matched text | grep -o '[0-9]+' file.txt |
| Invert — lines that do not match | grep -v debug app.log |
| Stop after N matches | grep -m 5 error app.log |
| Quiet — exit status only | grep -q error app.log |
| Suppress "No such file" errors | grep -s error missing.log |
Files and directories
Search one file or several named files. For full directory trees, see the grep recursive.
| When to use | Command |
|---|---|
| Search several files in one run | grep error file1.log file2.log |
Walk a directory tree (-r, --include, --exclude-dir) |
grep recursive search |
Context lines
Show surrounding log lines for debugging.
| When to use | Command |
|---|---|
| Lines after each match | grep -A 2 error app.log |
| Lines before each match | grep -B 2 error app.log |
| Lines before and after | grep -C 2 error app.log |
grep — command syntax
Synopsis from grep --help on Ubuntu 25.04 (GNU grep 3.11):
Usage: grep [OPTION]... PATTERNS [FILE]...
Search for PATTERNS in each FILE.
Example: grep -i 'hello world' menu.h main.c
Pattern selection and interpretation:
-E, --extended-regexp PATTERNS are extended regular expressions
-F, --fixed-strings PATTERNS are strings
-e, --regexp=PATTERNS use PATTERNS for matching
-f, --file=FILE take PATTERNS from FILE
-i, --ignore-case ignore case distinctions
-w, --word-regexp match only whole words
Output control:
-n, --line-number print line number with output lines
-c, --count print only a count of matching lines
-l, --files-with-matches print only names of FILEs with matches
-r, --recursive search directories recursivelyWith no FILE, grep reads standard input — the usual pattern in pipelines.
grep — command examples
Essential Search a log file for a string
The everyday task: find lines that contain a keyword in a text file.
Create a sample log and search it:
cat > app.log <<'EOF'
2026-07-01 INFO service started
2026-07-01 ERROR connection failed
2026-07-01 DEBUG cache hit
EOF
grep ERROR app.logSample output:
2026-07-01 ERROR connection failedgrep is case-sensitive by default — ERROR does not match error unless you add -i.
Essential Case-insensitive search with -i
Log levels are not always capitalized the same way. -i matches every case variant.
Run the command:
grep -i error app.logSample output:
2026-07-01 ERROR connection failedAdd -c when you only need a count: grep -ci error app.log prints 1 on this sample file.
Essential Filter command output through grep
Pipes send another command's stdout into grep — no temporary file required.
The same pattern works for ps aux | grep when hunting a PID; see the ps command for process columns before you filter.
Run the command:
echo -e 'alpha\nbeta\ngamma' | grep betaSample output:
betaThe same pattern works on real tools: journalctl -u nginx | grep -i error or ps aux | grep '[n]ginx' (brackets avoid matching the grep process itself).
Common Line numbers (-n) and match count (-c)
Line numbers help you jump to the spot in an editor; counts summarize how noisy a log is.
Run the commands:
grep -ni error app.log
grep -ci error app.logSample output:
2:2026-07-01 ERROR connection failed
1Use -n during incident triage and -c in monitoring scripts that only need above-zero checks.
Common Show lines that do not match (-v)
Filtering out noise — debug lines, health checks — is often easier than listing what you want.
Run the command:
grep -v -i debug app.logSample output:
2026-07-01 INFO service started
2026-07-01 ERROR connection failedCombine with pipes: apt list --installed 2>/dev/null | grep -v automatic to hide auto-installed packages.
Common Multiple patterns with -E
Extended regex lets you alternate patterns with | without running grep twice.
Run the command:
grep -Ei 'error|warning' app.logSample output:
2026-07-01 ERROR connection failedFor fixed strings with special characters, prefer -F or grep -F 'rate.limit' so dots are not regex wildcards.
Common List only filenames that match (-l)
When you care which file failed, not every matching line, -l prints filenames once.
Run the command:
cp app.log server.log
echo 'no issues here' > clean.log
grep -li error *.logSample output:
app.log
server.logPair with xargs for batch fixes: grep -l error *.log | xargs sed -i 's/ERROR/INFO/'.
Common Context after a match (-A)
Stack traces and multi-line errors make more sense with the lines that follow the match.
Run the command:
grep -A1 -i error app.logSample output:
2026-07-01 ERROR connection failed
2026-07-01 DEBUG cache hitUse -B for lines before the match and -C N for both sides — common when reading application stack dumps.
Advanced Whole-word match with -w
Without -w, searching for log also hits login and catalog.
Run the command:
echo 'log login logout' > words.txt
grep -w log words.txtSample output:
log login logoutOnly the standalone word log matches; login and logout are skipped because -w requires word boundaries.
Advanced Script check with -q (exit status only)
Scripts often only need to know whether a pattern exists — -q prints nothing and sets exit code 0 or 1.
Run the command:
grep -qi error app.log
echo "exit: $?"
grep -qi nomatch app.log
echo "exit: $?"Sample output:
exit: 0
exit: 1Use if grep -q pattern file; then … fi in shell conditionals. Combine with set -o pipefail when grep is in a pipeline that must signal failure.
grep — when to use / when not
| Use grep when | Use something else when |
|---|---|
|
grep vs awk
| grep | awk | |
|---|---|---|
| Job | Filter lines by pattern | Parse fields and compute on rows |
| Output | Matching lines (or counts/names) | Custom columns, sums, reports |
| Regex | Line-level | Field- and record-level |
| Best for | "Does this log line mention error?" | "Print the fifth column when column 3 > 100" |
Many pipelines chain them: grep error app.log | awk '{print $1,$4}'.
Related commands
| Command | One line |
|---|---|
| grep | Line-oriented pattern search (this page) |
Browse the full index in our Linux commands reference.
grep — interview corner
What does grep do?
grep reads input line by line and prints lines where the pattern matches. The name comes from ed's g/re/p — global regular expression print.
grep root /etc/passwd | head -1Sample output:
root:x:0:0:root:/root:/bin/bashA strong answer is:
"grep filters lines by pattern in files or stdin — I use it for logs, configs, and piped command output."
What is the difference between grep -E and egrep?
On modern GNU systems, egrep is grep -E — extended regular expressions with |, +, and groups without extra backslashes.
A strong answer is:
"grep -E enables extended regex; egrep is the same thing on GNU grep — I prefer grep -E for portability in scripts."
How do you search every file under a directory?
Use -r (or --recursive). For include/exclude globs, filename lists, and symlink behavior, see the grep recursive.
grep -r -i error /var/log --include='*.log' 2>/dev/null | headA strong answer is:
"grep -r pattern dir — I use the recursive cheat sheet for --include, --exclude-dir, and -l across trees."
What exit codes does grep return?
0 when a match is found, 1 when no match, 2 on errors (missing file, invalid regex). Scripts use -q to test presence silently.
A strong answer is:
"Exit 0 means match found, 1 means none, 2 means error — I use grep -q in conditionals and check PIPESTATUS in pipelines."
Why does grep highlight matches on Ubuntu?
Many distros alias grep to grep --color=auto. In scripts, call /usr/bin/grep or grep --color=never when escape codes would break parsing.
A strong answer is:
"Desktop Ubuntu often colorizes via alias — for scripts I use command grep or \grep to avoid ANSI codes in captured output."
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| No output but you expected matches | Case sensitivity or wrong pattern | Try -i; test with grep -E and simpler pattern |
grep: … No such file or directory |
Typo or missing path | Check path; use -s to hide errors in loops |
Matches login when you wanted log |
Substring match | Add -w for whole words |
Binary file matches |
Binary file without -a |
Use grep -a or skip binaries with --binary-files=without-match |
| Slow on huge trees | Searching everything | --include, --exclude-dir, or dedicated tools like ripgrep |
| Special characters behave oddly | Regex metacharacters | Use -F for fixed strings or escape metacharacters |
