Show every ERROR line with its line number
Problem statement
An on-call alert fired and you need to see what the API server logged. Print every line whose level is ERROR (uppercase), prefixed with its line number so you can jump to it in an editor. The lowercase error on the last line is free text, not a log level, and must not be printed.
app.log
2026-09-20 10:00:01 INFO Starting api server on :80802026-09-20 10:00:02 INFO Connected to database2026-09-20 10:00:15 WARN Slow query took 1200ms2026-09-20 10:01:03 ERROR Failed to reach payments service2026-09-20 10:01:04 INFO Retrying request2026-09-20 10:01:09 ERROR Payments service timeout after 5s2026-09-20 10:02:00 INFO Health check passed2026-09-20 10:02:30 INFO error budget report sentExamples
Example 1
Input: grep -n 'ERROR' app.log
Output: 4:2026-09-20 10:01:03 ERROR Failed to reach payments service
6:2026-09-20 10:01:09 ERROR Payments service timeout after 5s
Explanation: grep is case-sensitive by default, so line 8 is skipped.
Example 2
Input: grep -c 'ERROR' app.log
Output: 2
Explanation: -c prints only the number of matching lines.
Hints
Approach
Optimal
grep prints every line that contains the pattern. -n adds the 1-based line number and a colon in front of each match. Quoting the pattern in single quotes stops the shell from interpreting any special characters. Because grep matches case-sensitively by default, the lowercase error in the INFO message on line 8 is not printed, which is what we want. If you wanted to be stricter and match ERROR only as a whole word, add -w.
grep -n 'ERROR' app.logFollow-up questions
- How would you follow the log live and only print new ERROR lines? (
tail -f app.log | grep --line-buffered ERROR) - How would you search every rotated log, including
.gzfiles? (zgrep)
Frequently asked questions
-i makes the match case-insensitive, so it would also print line 8, where error is part of a normal INFO message. Match the exact casing your log format uses for levels. If levels can vary in case, anchor on the position instead, e.g. grep -nE '^[^ ]+ [^ ]+ ERROR '.
Use context flags: -B 2 prints 2 lines before each match, -A 2 after, and -C 2 both. grep separates non-adjacent groups with --.