Bash Shell

grep is a text search utility that can work with standard input or multiple files at once. It’s used to print out matches for patterns, strings, or regular expressions. It’s often useful to be able to count the number of matches, which grep can do pretty easily.

Counting Matches With grep

The grep command has the -c flag, which will count the number of lines matched and print out a number. This is useful for lots of things, such as searching through log files for the number of entries from a particle IP, endpoint, or other identifier.

grep -c "" /var/log/nginx/access.log

However, grep is able to match multiple times per line. If you use the -o flag, grep will print out a new line per match. This doesn’t work with the -c flag, as it will only count matching lines, not multiple matches per line.

A better solution is to use the wc (word count) utility with the -l (lines) parameter, which will count the raw number of lines passed to it over standard input. Using wc -l is the preferred solution because it works with -o to count the number of occurrences of the given string or pattern across the entire file.

grep -o "foo" file | wc -l

Counting Across Multiple Files

A nice feature of grep is the ability to handle multiple files at once, either passed through xargs, parameters, or supplied with wildcard expansion. When handling multiple files, grep will print out the filename before the match. When using -c to count the number of matching lines, it will also print out the filenames:

grep "foo" ./*.txt -cH

You should always use the -H flag when working with the possibility of multiple files, since it will always print the filename even if there’s only one file passed to grep. This will prevent automation from breaking if you depend on the filename being there.

If you want to use -o to count multiple matches per line, and pass the output to wc -l, you will unfortunately the ability to see the numbers for each individual file like with -c. However, with a bit of scripting, you can chop the first column off with cut, and count the number of unique occurrences for each filename with uniq -c:

grep "foo" ./*.txt -o | cut -d ':' -f 1 | uniq -c

RELATED: How to Extract and Sort Columns Out of Log Files on Linux

Profile Photo for Anthony Heddings Anthony Heddings
Anthony Heddings is the resident cloud engineer for LifeSavvy Media, a technical writer, programmer, and an expert at Amazon's AWS platform. He's written hundreds of articles for How-To Geek and CloudSavvy IT that have been read millions of times.
Read Full Bio »