web-dev-qa-db-fra.com

Compter toutes les occurrences d'une chaîne dans un grand nombre de fichiers avec grep

J'ai un tas de fichiers de log. J'ai besoin de savoir combien de fois une chaîne se produit dans tous les fichiers.

grep -c string *

résultats

...
file1:1
file2:0
file3:0
...

À l'aide d'un tuyau, je n'ai pu obtenir que les fichiers ayant une ou plusieurs occurrences:

grep -c string * | grep -v :0

...
file4:5
file5:1
file6:2
...

Comment puis-je obtenir uniquement le nombre combiné? (S'il renvoie file4:5, file5:1, file6:2, je veux récupérer 8.)

283
Željko Filipin
cat * | grep -c string
285
Bombe

Cela fonctionne pour plusieurs occurrences par ligne:

grep -o string * | wc -l
289
Jeremy Lavine
grep -oh string * | wc -w

comptera plusieurs occurrences dans une ligne

28
Kaofu

Au lieu d'utiliser -c, il suffit de le diriger vers wc -l.

grep string * | wc -l

Cela listera chaque occurrence sur une seule ligne, puis comptera le nombre de lignes.

Cela manquera les cas où la chaîne apparaît plus de 2 fois sur une ligne, cependant.

21
Michael Haren
cat * | grep -c string

Une des rares applications utiles de cat.

16
Joachim Sauer

Quelque chose de différent de toutes les réponses précédentes:

Perl -lne '$count++ for m/<pattern>/g;END{print $count}' *
9
Vijay

Vous pouvez ajouter -R pour effectuer une recherche récursive (et éviter d'utiliser cat) et -I pour ignorer les fichiers binaires.

grep -RIc string .
7
azmeuk

Solution AWK obligatoire:

grep -c string * | awk 'BEGIN{FS=":"}{x+=$2}END{print x}'

Faites attention si vos noms de fichiers incluent ":" bien.

6
mumrah

La solution AWK qui gère également les noms de fichiers, y compris les deux points:

grep -c string * | sed -r 's/^.*://' | awk 'BEGIN{}{x+=$1}END{print x}'

N'oubliez pas que cette méthode ne fait toujours pas rechercher plusieurs occurrences de string sur la même ligne.

5
Kreuvf

Si vous voulez un nombre d'occurrences par fichier (exemple pour la chaîne "tcp"):

grep -RIci "tcp" . | awk -v FS=":" -v OFS="\t" '$2>0 { print $2, $1 }' | sort -hr

Exemple de sortie:

53  ./HTTPClient/src/HTTPClient.cpp
21  ./WiFi/src/WiFiSTA.cpp
19  ./WiFi/src/ETH.cpp
13  ./WiFi/src/WiFiAP.cpp
4   ./WiFi/src/WiFiClient.cpp
4   ./HTTPClient/src/HTTPClient.h
3   ./WiFi/src/WiFiGeneric.cpp
2   ./WiFi/examples/WiFiClientBasic/WiFiClientBasic.ino
2   ./WiFiClientSecure/src/ssl_client.cpp
1   ./WiFi/src/WiFiServer.cpp

Explication:

  • grep -RIci NEEDLE . - recherche la chaîne NEEDLE de manière récursive dans le répertoire actuel (suivant les liens symboliques), en ignorant les fichiers binaires, en comptant le nombre d'occurrences, en ignorant la casse
  • awk ... - cette commande ignore les fichiers sans occurrences et les lignes de format
  • sort -hr - trie les lignes dans l'ordre inverse des nombres dans la première colonne

Bien sûr, cela fonctionne aussi avec d'autres commandes grep avec l'option -c (count). Par exemple:

grep -c "tcp" *.txt | awk -v FS=":" -v OFS="\t" '$2>0 { print $2, $1 }' | sort -hr
4
Andriy Makukha

version courte récursive:

find . -type f -exec cat {} + | grep -c 'string'
3
Dmitry Tarashkevich

Vous pouvez utiliser un simple grep pour capturer efficacement le nombre d'occurrences. Je vais utiliser l'option -i pour m'assurer que STRING/StrING/string soit capturé correctement.

Ligne de commande qui donne le nom du fichier:

grep -oci string * | grep -v :0

Ligne de commande qui supprime les noms de fichiers et affiche 0 s'il existe un fichier sans occurrences:

grep -ochi string *
3
Mitul Patel

Seule solution Grep que j'ai testée avec grep pour Windows:

grep -ro "pattern to find in files" "Directory to recursively search" | grep -c "pattern to find in files"

Cette solution comptera toutes les occurrences même s'il y en a plusieurs sur une même ligne. -r cherche récursivement dans le répertoire, -o affichera uniquement "la partie d'une ligne correspondant à PATTERN" - c'est ce qui divise plusieurs occurrences sur une seule ligne et permet à grep d'imprimer chaque correspondance sur une nouvelle ligne ; puis redirigez ces résultats séparés par une nouvelle ligne dans grep avec -c pour compter le nombre d'occurrences utilisant le même modèle.

1
Quantic

Voici un moyen alternatif plus rapide que grep AWK de le faire, qui gère plusieurs correspondances de <url> par ligne, au sein d'une collection de fichiers XML dans un répertoire:

awk '/<url>/{m=gsub("<url>","");total+=m}END{print total}' some_directory/*.xml

Cela fonctionne bien dans les cas où certains fichiers XML ne comportent pas de saut de ligne.

1
Excalibur

Un autre outil utilisant des fonctions de base de ligne de commande gérant plusieurs occurrences par ligne.

 cat * |sed s/string/\\\nstring\ /g |grep string |wc -l
0
NTwoO