Par exemple, j'ai un fichier 1.txt
contenant:
Moscow
Astana
Tokyo
Ottawa
Je veux compter le nombre de tous les caractères comme:
a - 4,
b - 0,
c - 1,
...
z - 0
command-line
bash
text-processing
Set-xx
la source
la source
Réponses:
Vous pouvez utiliser ceci:
La
sed
partie place une nouvelle ligne après chaque personnage. Ensuite, noussort
sortons par ordre alphabétique. Etuniq
compte enfin le nombre d'occurrences. Le-i
drapeau deuniq
peut être omis si vous ne voulez pas insensibilité à la casse.la source
sort -k 2
pour les répertorier de manière alphanumérique.sed -e $'s/\(.\)/\\1\\\n/g'
(voir aussi stackoverflow.com/a/18410122/179014 )| sort -rnk 1
. Et si vous avez affaire à de très gros fichiers, comme moi, vous pouvez simplement échantillonner quelques milliers de lignes pour obtenir un proxy pour lescat 1.txt | shuf -n 10000 | sed 's/\(.\)/\1\n/g' | sort | uniq -ic | sort -rnk 1
Un peu en retard, mais pour compléter l'ensemble, une autre approche python (3), résultat trié:
Explication
Lisez le fichier, sautez les espaces et retournez comme "caractères":
Créez un ensemble (trié) d'uniques:
Comptez et imprimez l'occurrence pour chacun des caractères:
Comment utiliser
chars_count.py
Exécutez-le avec le fichier comme argument soit:
si le script est exécutable, ou:
si ce n'est pas
la source
Par défaut dans awk le F ield S eparator (FS) est un espace ou un onglet . Puisque nous voulons compter chaque caractère, nous devrons redéfinir le FS à rien (
FS=""
) pour diviser chaque caractère sur une ligne distincte et l'enregistrer dans un tableau et à la fin duEND{..}
bloc, imprimer leurs occurrences totales par la commande awk suivante :En
{for (i=1;i<=NF;i++) a[$i]++} ... FS="" ...
bloc, nous divisons simplement les caractères. Eten
END{for (c in a) print c,a[c]}
bloc, nous bouclons vers le tableaua
et imprimons le caractère enregistré dedansprint c
et son nombre d'occurrencesa[c]
la source
Faites une
for
boucle pour tous les caractères que vous souhaitez compter, et utilisezgrep -io
pour obtenir toutes les occurrences du caractère et de la casse ignorée, etwc -l
pour compter les instances, et imprimer le résultat.Comme ça:
Le script génère ceci:
MODIFIER après commentaire
Pour créer une boucle pour tous les caractères imprimables, vous pouvez procéder comme suit:
Cela comptera tous les caractères ANSI de 32 à 126 - ce sont les plus lisibles. Notez que cela n'utilise pas ignorer la casse.
la sortie de ceci sera:
la source
i
du grep. (dans votre question vous n'aviez que 3 dans le résultat attendu)grep
l'entrée entière à plusieurs reprises.Voici une autre solution (en awk) ...
la source
cat file | awk '...'
: vous pouvez dire directementawk '...' file
.L'
perl
oneliner suivant fera le décompte. Je mets l'expression régulière dans le contexte de la liste (pour obtenir le nombre de correspondances) et le mets dans un contexte scalaire:la source
perl -Mfeature=say -e '$a=join("",<>);say join(",\n", map { sprintf("%s - %d", $_, ($d=()=$a=~/$_/gi)); } ("a".."z"))'
Voici une solution utilisant Python:
Ici, nous avons utilisé la classe
collections
du moduleCounter
pour compter le nombre d'occurrences de chaque caractère, puis à des fins d'impression, nous avons utilisé lestring
module pour obtenir toutes les lettres minuscules par la variablestring.lowercase
.Enregistrez le script ci-dessus dans un fichier en lui donnant le nom que vous voulez, par exemple
count.py
. Maintenant, à partir du même répertoire où le fichier est enregistré, vous pouvez simplement exécuterpython count.py
pour exécuter le fichier, à partir de tout autre répertoire, utilisez le chemin absolu du fichier pour l'exécuter, c'est-à-direpython /absolute/path/to/count.py
.la source
Il y a quelque temps, j'ai écrit un programme C pour cela, car j'en avais besoin pour regarder des fichiers volumineux et produire des statistiques.
compiler avec (en supposant que le code source réside
character-distribution.c
):courir avec:
Si vous n'avez pas de compilateur C prêt, installez GCC:
la source
Solution similaire à @heemayl, avec un code plus strict, qui fonctionne sur Python 2.7 et Python 3.
La première déclaration
count = collections.Counter(…)
fait tout le vrai travail.fileinput.input()
lit chaque ligne de l'entrée, qui peut être canalisée via stdin ou comme arguments de ligne de commande.*
le fait considérer un personnage à la fois plutôt qu'une ligne à la fois.count = Counter(…)
compte les occurrences de chaque caractère efficacement, en une seule passe, et stocke le résultat dans lacount
variable.La deuxième ligne imprime simplement les résultats.
'{} - {}'.format(c, count[c] + count[c.upper()]) for c in string.ascii_lowercase
fait une liste de chaque personnage et son nombre.print(',\n'.join(…))
le met au format souhaité: un par ligne, séparé par des virgules, mais pas de virgule sur la dernière ligne.la source
GNU awk 4.1
Si vous avez une version antérieure de GNU awk, vous pouvez l'utiliser
for (c in b) print c, b[c]
.la source
Voici la réponse en utilisant rubis. Cela se fait en changeant la chaîne en une liste uniq des différents caractères et en utilisant la méthode de comptage sur chacun d'eux.
la source