Si vous avez GNU grep (toujours sur Linux et Cygwin, parfois ailleurs), vous pouvez compter les lignes de sortie degrep -o
: grep -o needle | wc -l
.
Avec Perl, voici quelques manières que je trouve plus élégantes que la vôtre (même après que ce soit réglé ).
perl -lne 'END {print $c} map ++$c, /needle/g'
perl -lne 'END {print $c} $c += s/needle//g'
perl -lne 'END {print $c} ++$c while /needle/g'
Avec les seuls outils POSIX, une approche, si possible, consiste à scinder l’entrée en lignes avec une seule correspondance avant de la transmettre à grep. Par exemple, si vous recherchez des mots entiers, commencez par transformer chaque caractère non-mot en une nouvelle ligne.
# equivalent to grep -ow 'needle' | wc -l
tr -c '[:alnum:]' '[\n*]' | grep -c '^needle$'
Sinon, il n'y a pas de commande standard pour effectuer ce traitement de texte particulier, vous devez donc vous tourner vers sed (si vous êtes masochiste) ou awk.
awk '{while (match($0, /set/)) {++c; $0=substr($0, RSTART+RLENGTH)}}
END {print c}'
sed -n -e 's/set/\n&\n/g' -e 's/^/\n/' -e 's/$/\n/' \
-e 's/\n[^\n]*\n/\n/g' -e 's/^\n//' -e 's/\n$//' \
-e '/./p' | wc -l
Voici une solution plus simple utilisant sed
and grep
, qui fonctionne pour les chaînes ou même les expressions rationnelles mais qui échoue dans certains cas avec des motifs ancrés (par exemple, elle trouve deux occurrences de ^needle
ou \bneedle
dans needleneedle
).
sed 's/needle/\n&\n/g' | grep -cx 'needle'
Notez que dans les substitutions sed ci-dessus, je voulais \n
dire une nouvelle ligne. Ceci est standard dans la partie motif, mais dans le texte de remplacement, remplacez la barre oblique inverse par une nouvelle barre oblique inversée \n
.
grep
est spécifié, mais pour quiconque utiliseack
, la réponse est simpleack -ch <pattern>
.