Consider using grep -c instead of grep|wc -l
Counting matches with `grep pattern | wc -l` spawns two processes. `grep -c` does it in one.
Problem
Piping grep into wc is harmless in a one-off script but wasteful in loops or hot paths. `grep -c` returns the count directly and is one line shorter.
Bad
n=$(grep ERROR log | wc -l)Good
n=$(grep -c ERROR log)Explanation
Note: `grep -c` counts matching lines, not occurrences. For total occurrences across lines, use `grep -o pattern file | wc -l`.
When It Matters
grep | wc -l spawns a second process and pipes every matching line through it purely to count them. On a small log that costs a millisecond; inside a loop over thousands of files, or on a multi-gigabyte log, the extra process and the full-text transfer dominate the runtime. grep -c does the counting in the same pass it was already making. There is a correctness angle too. wc -l counts newlines, so a final match with no trailing newline is undercounted, and leading whitespace in the wc output breaks naive arithmetic and string comparisons.
Second Example
Note
grep exits with status 1 when it finds nothing, so under set -e you need "|| true" or an explicit test around the assignment.
Exceptions
grep -c counts matching lines, not matching occurrences. If a line can contain several matches and you need the total number of matches, grep -o pattern file | wc -l is the correct tool and the warning does not apply. The same is true when you are counting lines that survived several filters in a pipeline; there is no single grep to move the count into.
Faq
Q
Does grep -c count matches or lines?
A
Lines. Each input line that matches counts once, no matter how many times the pattern occurs in it. Use grep -o pattern | wc -l when you need per-occurrence counts.
Q
Why is my count wrong when grep finds nothing?
A
grep exits 1 on no match. Under set -e that aborts the script, and in a conditional the assignment appears to fail. Wrap it as n=$(grep -c ... ) || true, or test the exit status explicitly.
Q
I only need to know whether there is a match — is -c right?
A
No. Use grep -q, which stops reading as soon as it finds the first match and produces no output at all. Counting every match to then compare against zero reads the entire file for no reason.