No grep cannot do this in one pass, I would suggest using awk:
awk -v pat='alfa beta gamma' '
BEGIN { split(pat, p) }
{ for(k in p) if($0 ~ p[k]) c[k]++ }
END { for(k in p) print p[k], c[k]?c[k]:0 }
'
Or as a rather long one-liner:
awk -v pat='alfa beta gamma' 'BEGIN { split(pat, p) } { for(k in p) if($0 ~ p[k]) c[k]++ } END { for(k in p) print p[k], c[k]?c[k]:0 }'
Explanation
pat is split into the p array, which is then used to search for matches on each line ($0 ~ p[k]). The counters are held in the c array. The c[k]?c[k]:0 bit uses the ternary operator to print 0 when c[k] is zero.
Note if your pattern contains space, you need to use a different delimiter between the patterns in pat and to update the split command accordingly.
Testing
Input:
cat << EOF > file
alfa
beta
gamma
gamma
EOF
Output with pat='alfa beta gamma':
alfa 1
beta 1
gamma 2
Input:
cat << EOF > file
alfa beta
beta
gamma gamma
gamma alfa
alfalfa
alfa alfa
EOF
Output with pat='^a a$ alfa beta gamma':
beta 2
gamma 2
^a 3
a$ 6
alfa 4
The output matches in both cases the output from running grep -c with each pattern individually.
sort file | uniq -cand thengrepon that? – slhck♦ Jan 8 at 11:24alfax,alfay,alfaz(on separate lines), this script will report1 alfax/1 alfay/1 alfazrather than3 alfa. An input line ofalfa beta(on the same line) will result in a report of1 alfa betarather than1 alfa/1 beta. – Scott Jan 8 at 18:38