Grep: count number of matches per line
I'm trying to get the number of matches (in this case occurrences of {
or }
) in each line of a .tex file.
I know that the -o
flag returns only the match, but it returns each match on a new line, even combined with the -n
flag. I don't know of anything I could pipe this through to count the repeats. The -c
flag only returns the total number of matches in the entire file - maybe I could pipe one line at a time to grep?
grep -o -n '[{}]' <filename> | cut -d : -f 1 | uniq -c
The output will be something like:
3 1
1 2
Meaning 3 occurrences in the first line and 1 in the second.
Taken from https://stackoverflow.com/a/15366097/3378354 .
After reading various solutions, I think this is the easiest approach to the problem:
while read i; do echo $i |grep -o "matchingString"| wc -l; done < input.txt
Is using grep
a requirement? Here’s an alternative:
sed 's/[^{}]//g' your_file | awk '{print NR, length }'
The sed
strips out all characters other than {
and }
(i.e., leaving only {
and }
characters),
and then the awk
counts the characters on each line (which are just the {
and }
characters).
To suppress lines with no matches,
sed 's/[^{}]//g' your_file | awk '/./ {print NR, length }'
Note that my solution assumes (requires) that the strings you are looking for are single characters. Moebius’s answer is more easily adapted to multi-character strings. Also, neither of our answers excludes quoted or escaped occurrences of the characters/strings of interest; e.g.,
{ "nullfunc() {}" }
would be considered to contain four brace characters.
AWK can do this by itself, piping multiple processes is not necessary.
awk '{print NR " " gsub(/[{}]/, "")}'
Example:
$ printf 'test{}\n abc\n }{{}\n xyz}' | awk '{print NR " " gsub(/[{}]/, "")}'
1 2
2 0
3 4
4 1
The grep
count option -c
is a con job. It does not return the total count you expect (it is actually just a line count, not a match count).
$ printf 'test{}\n abc\n }{{}\n xyz}' | grep -con "[{}]"
3
awk
can get a total count like this:
$ printf 'test{}\n abc\n }{{}\n xyz}' | awk -F"[{}]" '{c+=NF-1} END {print c}'
7