grep: Usage, Options & Common CI Errors
grep prints the lines that match a pattern (and exits non-zero when none do).
grep is the most-used filter in CI. Its defining gotcha: "no match" is exit code 1, which under set -e or in a pipeline aborts the whole job - that is a feature, not a failure.
What it does
grep searches input for lines matching a regular expression and prints them. Its exit status is the real product in scripts: 0 = matched, 1 = no match, 2 = error (e.g. unreadable file).
Common usage
grep "TODO" file.txt
grep -r "apiKey" src/ # recursive
grep -rn --include='*.ts' "fixme" . # line numbers, file glob
grep -E '^(feat|fix):' msg.txt # extended regex
grep -q "PASS" results.txt && echo ok # -q: just the exit code
grep -v "^#" config # invert: drop commentsOptions
| Flag | What it does |
|---|---|
| -r / -R | Recurse into directories |
| -i | Case-insensitive |
| -E | Extended regex (grep -E ~ egrep) |
| -q | Quiet; exit status only |
| -v | Invert match |
| -c / -o / -l | Count / only-match / file names |
Common errors in CI
The classic: a grep that finds nothing exits 1, and with set -e (or as the last command in a step) that aborts the job even though "no matches" was the desired result. Guard it: grep -q X file || true, or test the status explicitly. Exit 2 is a real error (bad path/regex). Beware grep -P (Perl regex) is GNU-only and absent on Alpine/BusyBox grep.