grep can count matching lines in a stream. A script can keep the search term in a variable so the same pipeline answers different questions.

Program

Play the script to count matching log lines after choosing the search pattern.

pattern
grep_counts.sh
Replay: real traced execution (multi-file project)
#!/usr/bin/env bash

log=$'info boot\nwarn disk\nerror fail\ninfo done'
pattern="error"
matches="$(printf '%s\n' "$log" | grep -c "$pattern")"
echo "$pattern:$matches"
#!/usr/bin/env bash

log=$'info boot\nwarn disk\nerror fail\ninfo done'
pattern="warn"
matches="$(printf '%s\n' "$log" | grep -c "$pattern")"
echo "$pattern:$matches"
#!/usr/bin/env bash

log=$'info boot\nwarn disk\nerror fail\ninfo done'
pattern="info"
matches="$(printf '%s\n' "$log" | grep -c "$pattern")"
echo "$pattern:$matches"
  1. log ← info boot, warn disk, error fail, info done

    3log=$'info boot\nwarn disk\nerror fail\ninfo done'4pattern="error"
    values this stepinfo boot, warn disk, error fail, info donelog
  2. pattern ← error

    3log=$'info boot\nwarn disk\nerror fail\ninfo done'4pattern="error"5matches="$(printf '%s\n' "$log" | grep -c "$pattern")"
    values this steperrorpattern
  3. matches ← 1

    4pattern="error"5matches="$(printf '%s\n' "$log" | grep -c "$pattern")"6echo "$pattern:$matches"
    values this step1matcheserrorpattern
  4. echo "$pattern:$matches"

    5matches="$(printf '%s\n' "$log" | grep -c "$pattern")"6echo "$pattern:$matches"
    outputerror:1
    values this steperrorpattern1matches
  1. log ← info boot, warn disk, error fail, info done

    3log=$'info boot\nwarn disk\nerror fail\ninfo done'4pattern="warn"
    values this stepinfo boot, warn disk, error fail, info donelog
  2. pattern ← warn

    3log=$'info boot\nwarn disk\nerror fail\ninfo done'4pattern="warn"5matches="$(printf '%s\n' "$log" | grep -c "$pattern")"
    values this stepwarnpattern
  3. matches ← 1

    4pattern="warn"5matches="$(printf '%s\n' "$log" | grep -c "$pattern")"6echo "$pattern:$matches"
    values this step1matcheswarnpattern
  4. echo "$pattern:$matches"

    5matches="$(printf '%s\n' "$log" | grep -c "$pattern")"6echo "$pattern:$matches"
    outputwarn:1
    values this stepwarnpattern1matches
  1. log ← info boot, warn disk, error fail, info done

    3log=$'info boot\nwarn disk\nerror fail\ninfo done'4pattern="info"
    values this stepinfo boot, warn disk, error fail, info donelog
  2. pattern ← info

    3log=$'info boot\nwarn disk\nerror fail\ninfo done'4pattern="info"5matches="$(printf '%s\n' "$log" | grep -c "$pattern")"
    values this stepinfopattern
  3. matches ← 2

    4pattern="info"5matches="$(printf '%s\n' "$log" | grep -c "$pattern")"6echo "$pattern:$matches"
    values this step2matchesinfopattern
  4. echo "$pattern:$matches"

    5matches="$(printf '%s\n' "$log" | grep -c "$pattern")"6echo "$pattern:$matches"
    outputinfo:2
    values this stepinfopattern2matches

Follow the Count

  1. log contains four lines: info boot, warn disk, error fail, and info done.
  2. pattern starts as error.
  3. grep -c "$pattern" counts matching lines.
  4. Only error fail matches the default pattern.
  5. The script prints error:1. | pattern | matching lines | output | | --- | --- | --- | | error | error fail | error:1 | | warn | warn disk | warn:1 | | info | info boot, info done | info:2 |
grep -c `grep -c` prints the number of matching lines instead of the lines themselves.
quoted pattern Quoting `$pattern` keeps the selected search text as one argument.
pipeline `printf ... | grep ...` sends generated text directly into the filter.

Exercise: grep_counts.sh

Reproduce error:1, then change pattern to the pinned variants warn and info and predict warn:1 and info:2.