grep -c
est utile pour déterminer le nombre de fois qu'une chaîne se produit dans un fichier, mais ne compte chaque occurrence qu'une fois par ligne. Comment compter plusieurs occurrences par ligne?
Je cherche quelque chose de plus élégant que:
perl -e '$_ = <>; print scalar ( () = m/needle/g ), "\n"'
grep
est spécifié, mais pour quiconque utiliseack
, la réponse est simpleack -ch <pattern>
.Réponses:
grep ne
-o
sortira que les correspondances en ignorant les lignes;wc
peut les compter:Cela correspondra également à «aiguilles» ou «multineedle».
Seulement des mots simples:
la source
\b
et\B
faire ici?uniq
ne supprime que les lignes identiques adjacentes; vous devez le fairesort
avant de vous alimenteruniq
si vous n'êtes pas déjà sûr que les doublons seront toujours immédiatement adjacents.Si vous avez GNU grep (toujours sur Linux et Cygwin, parfois ailleurs), vous pouvez compter les lignes de sortie de
grep -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é ).
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.
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.
Voici une solution plus simple utilisant
sed
andgrep
, 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
dansneedleneedle
).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
.la source
Si, comme moi, vous vouliez réellement
"les deux; chacun exactement une fois",(c'est en fait "deux fois"), alors c'est simple:et vérifiez la sortie
2
.L'avantage de cette approche (si exactement une fois est ce que vous voulez) est qu'elle évolue facilement.
la source
Une autre solution utilisant awk et
needle
comme séparateur de champs:Si vous souhaitez faire correspondre le
needle
texte suivi de la ponctuation, modifiez le séparateur de champs en conséquence, c.-à-d.Ou utilisez la classe:
[^[:alnum:]]
pour englober tous les caractères non alpha.la source
Votre exemple n'indique que le nombre d'occurrences par ligne et non le total du fichier. Si c'est ce que vous voulez, quelque chose comme ceci pourrait fonctionner:
la source
Ceci est ma solution pure bash
la source