grep output control and scripting

grep, sed & awk · Practical · 10 min

Context lines make logs readable, and grep's exit status is the idiomatic 'does this file contain X?' test in shell scripts.

When reading logs you usually want the lines around a match. -A 3 prints three lines after each match, -B 3 three before, -C 3 both. Groups of context are separated by -- lines.

Other output controls:

  • -m N stops after N matching lines (per file), which is fast on huge files.
  • -o prints only the matched parts, one per line; combine with -E to extract IDs, IPs or URLs.
  • --color=auto highlights matches on a terminal.
  • -Z / --null ends file names with a NUL byte for safe use with xargs -0.

grep's exit status is designed for scripts: 0 if any line matched, 1 if none matched, 2 on an error such as a missing file. With -q (quiet) grep prints nothing and exits on the first match, so it is the standard way to test for presence:

if grep -q '^backup:' /etc/passwd; then echo "user exists"; fi

Be careful in scripts using set -e or pipefail: a grep that finds nothing returns 1, which counts as a failure. If "no matches" is fine, write grep ... || true.

-s suppresses messages about unreadable files, useful with broad recursive searches.

Example

printf 'start\nload config\nERROR disk full\nretry\nok\nERROR timeout\n' > app.log

grep -B1 -A1 ERROR app.log
# load config
# ERROR disk full
# retry
# --
# ok
# ERROR timeout

grep -m1 ERROR app.log                  # ERROR disk full
grep -oE 'ERROR [a-z]+' app.log         # ERROR disk / ERROR timeout

if grep -q 'timeout' app.log; then
  echo "saw a timeout"                  # saw a timeout
fi
grep -q 'panic' app.log; echo "status $?"   # status 1

Remember

  • -A/-B/-C add context lines after, before or around matches
  • Exit status: 0 = matched, 1 = no match, 2 = error
  • grep -q in an if is the idiomatic presence test

Watch out for

  • A grep with no matches failing a set -e script; add || true when an empty result is acceptable.

Check yourself

  1. A script runs grep -q pattern file. Which exit status means the file exists but contains no match?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.gnu.org/software/grep/manual/grep.html#Exit-Status