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
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 "188.8.131.52" /var/log/nginx/access.log
grep is able to match multiple times per line. If you use the
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
grep "foo" ./*.txt -o | cut -d ':' -f 1 | uniq -c