Compter les occurrences d'un caractère dans un fichier texte brut

132

Existe-t-il un moyen sous linux / terminal de compter, combien de fois le caractère f apparaît-il dans un fichier texte brut?

Cupakob
la source
9
Techniquement, cela pourrait être considéré comme un sh / bash / etc. question de programmation, donc je pense qu'il a une validité dans les deux endroits.
Rob Hruska
@Rob Hruska: oui, je pense aussi que la programmation bash ... @abrashka: la réponse à votre première et deuxième question est "NON"!
cupakob

Réponses:

178

Que dis-tu de ça:

fgrep -o f <file> | wc -l

Remarque: En plus d'être beaucoup plus facile à mémoriser / dupliquer et personnaliser, c'est environ trois fois (désolé, éditez! A bâclé le premier test) que la réponse de Vereb.

Cascabel
la source
Celui-ci ne fonctionne pas si vous avez besoin de compter \rou de \ncaractères; la tr -cd fréponse fonctionne pour cela.
bjnord
3
Pour compter plusieurs caractères, par exemple a, bet c, utilisez egrep: egrep -o 'a|b|c' <file> | wc -l.
Skippy le Grand Gourou
Aussi, veillez à NE PAS utiliser wc -ccomme dans la trréponse: puisque les grepsorties ligne par ligne, wccompteraient les fins de lignes comme des caractères (d'où le doublement du nombre de caractères).
Skippy le Grand Gourou
@bjnord Ok pour \r, mais pour compter \npourquoi ne pas simplement utiliser wc -l?
Skippy le Grand Gourou
67

même plus vite:

tr -cd f < file | wc -c

Temps pour cette commande avec un fichier avec 4,9 Mo et 1100000 occurrences du caractère recherché:

real   0m0.089s
user   0m0.057s
sys    0m0.027s

Temps de réponse Vereb avec echo, cat, tret bcpour le même fichier:

real   0m0.168s
user   0m0.059s
sys    0m0.115s

Le temps de réponse Rob Hruska avec tr, sedet wcpour le même fichier:

real   0m0.465s
user   0m0.411s
sys    0m0.080s

Il est temps de répondre Jefromi avec fgrepet wcpour le même fichier:

real   0m0.522s
user   0m0.477s
sys    0m0.023s 
user1985553
la source
3
Pour compter plusieurs caractères, par exemple a, bet c: tr -cd abc < file | wc -l.
Skippy le Grand Gourou
êtes-vous sûr? n'était pas supposé être à la tr -cd abc < file | wc -cplace
Mithun B
10
echo $(cat <file>  | wc -c) - $(cat <file>  | tr -d 'A' | wc -c) | bc

où le A est le caractère

Temps pour cette commande avec un fichier avec 4,9 Mo et 1100000 occurrences du caractère recherché:

real   0m0.168s
user   0m0.059s
sys    0m0.115s
Vereb
la source
1
Cela devient environ un tiers plus rapide si vous supprimez les cats inutiles , en donnant le nom de fichier comme argument à wcet tr.
Cascabel
1
Si vous voulez vraiment optimiser cela lit le fichier une seule fois: echo $ (stat -c% s <fichier>) - $ (cat <fichier> | tr -d 'A' | wc -c) | bc
Vereb
@Vereb - tr ne lit que stdin, mais cela peut être diffusé plutôt que cated:tr -d 'A' < <file> | wc ...
dsz
7

Si tout ce que vous avez à faire est de compter le nombre de lignes contenant votre personnage, cela fonctionnera:

grep -c 'f' myfile

Cependant, il compte plusieurs occurrences de «f» sur la même ligne comme une seule correspondance.

Jongo le Gibbon
la source
4

tr -d '\n' < file | sed 's/A/A\n/g' | wc -l

Remplacement des deux occurrences de «A» par votre caractère et de «fichier» par votre fichier d'entrée.

  • tr -d '\n' < file: supprime les nouvelles lignes
  • sed 's/A/A\n/g: ajoute une nouvelle ligne après chaque occurrence de "A"
  • wc -l: compte le nombre de lignes

Exemple:

$ cat file
abcdefgabcdefgababababbbba


1234gabca

$ tr -d '\n' < file | sed 's/a/a\n/g' | wc -l
9
Rob Hruska
la source