164 votes

Compter les occurrences d'un caractère dans une chaîne de caractères en utilisant Bash

Je dois compter les nombre d'occurrences d'un caractère dans une chaîne de caractères en utilisant Bash.

Dans l'exemple suivant, lorsque le caractère est (par exemple) t il echo s le nombre correct d'occurrences de t sur var mais lorsque le caractère est une virgule ou un point-virgule, le résultat est zéro :

var = "text,text,text,text" 
num = `expr match $var [,]`
echo "$num"

165voto

jm666 Points 17312

Vous pouvez par exemple supprimer tous les autres caractères et compter ce qui reste, comme :

var="text,text,text,text"
res="${var//[^,]}"
echo "$res"
echo "${#res}"

imprimera

,,,
3

ou

tr -dc ',' <<<"$var" | awk '{ print length; }'

ou

tr -dc ',' <<<"$var" | wc -c    #works, but i don't like wc.. ;)

ou

awk -F, '{print NF-1}' <<<"$var"

ou

grep -o ',' <<<"$var" | grep -c .

ou

perl -nle 'print s/,//g' <<<"$var"

129voto

hek2mgl Points 38787

J'utiliserais les éléments suivants awk commandement :

string="text,text,text,text"
char=","
awk -F"${char}" '{print NF-1}' <<< "${string}"

Je divise la chaîne par $char et imprimer le nombre de champs résultants moins 1.

Si votre shell ne prend pas en charge l'option <<< l'opérateur, utilisez echo :

echo "${string}" | awk -F"${char}" '{print NF-1}'

106voto

Robin Hsu Points 231

Vous pouvez le faire en combinant tr y wc les commandes. Par exemple, pour compter e dans la chaîne referee

echo "referee" | tr -cd 'e' | wc -c

sortie

4

Explications : Commande tr -cd 'e' supprime tous les caractères autres que 'e', et la commande wc -c compte les caractères restants.

Les lignes d'entrée multiples sont également bonnes pour cette solution, comme la commande cat mytext.txt | tr -cd 'e' | wc -c peut compter e dans le fichier mytext.txt même si le fichier peut contenir de nombreuses lignes.

*** Mise à jour ***

Pour résoudre le problème des espaces multiples devant le numéro (@tom10271), il suffit d'ajouter une commande tr pipée :

 tr -d ' '

Par exemple :

echo "referee" | tr -cd 'e' | wc -c | tr -d ' '

10voto

Matthew Snyder Points 46

Awk est très cool, mais pourquoi ne pas le garder simple ?

num=$(echo $var | grep -o "," | wc -l)

7voto

rmanna Points 632

Suite aux réponses et commentaires de chacun, voici la version la plus courte et la plus douce :

grep -o "$needle" <<< "$haystack" | wc -l

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X