Skip to content
shellhacks.dev
Text Processing

Count every occurrence not just lines

Count every occurrence of a word with grep -o piped to wc -l, because grep -c counts the lines that match and a line with three hits counts as one.

1 min read
Summarize in AI

A word appears several times on some lines, and the count you need is the number of times it appears, not the number of lines it appears on.

Shell
printf 'to be or not to be\nbe\nmaybe\n' > lines.txt
grep -c be lines.txt
grep -o be lines.txt | wc -l
grep -ow be lines.txt | wc -l
Text
3
4
3

-o prints each non-empty match on a line of its own, so wc -l counts matches rather than lines. The documented behaviour is in the GNU grep manual. The third command adds -w, which keeps whole words only, so the "be" inside "maybe" no longer counts: 4 hits become 3. Use -w whenever a short word can sit inside a longer one.

Matches cannot overlap, so counting "aa" in "aaa" gives 1, not 2. The pipeline also reads the whole input and prints every match first, which is slow for a very large file with millions of hits. In that case let awk count with gsub instead.

Share

More snippets

Text Processing

Search recursively and skip binary files

Skip binary files in a recursive grep with --binary-files=without-match, short form below. Otherwise GNU grep 3.8 prints a notice for every binary hit.

1 min read
Text Processing

Count the matches per file

Count the matching lines in each file with grep -c. With several files grep prefixes each count with the name, and -h removes the prefix for one total.

1 min read
Text Processing

Match whole words only

Match whole words only with grep -w. A match must sit between non-word characters, and letters, digits and the _ character all count as word characters.

1 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.