Comment puis-je compter les termes uniques dans un fichier texte en clair, sans tenir compte de la casse?

Cela peut être dans n’importe quel langage de haut niveau qui est susceptible d’être disponible sur un système similaire à unix (Python, Perl, awk, unix standard unix {sort, uniq}, etc.). Si tout va bien, il est assez rapide pour signaler le nombre total de termes uniques pour un fichier texte de 2 Mo.

Je n’en ai besoin que pour une vérification rapide, de sorte qu’il n’a pas besoin d’être bien conçu.

Rappelez-vous, insensibles à la casse.

Merci beaucoup les gars.

Remarque: Si vous utilisez Python, veuillez ne pas utiliser le code de la version 3 uniquement. Le système sur lequel je l’exécute n’a que 2.4.4.

Dans Python 2.4 (peut-être fonctionne-t-il également sur les systèmes antérieurs):

#! /usr/bin/python2.4 import sys h = set() for line in sys.stdin.xreadlines(): for term in line.split(): h.add(term) print len(h) 

En Perl:

 $ perl -ne 'for (split(" ", $_)) { $H{$_} = 1 } END { print scalar(keys%H), "\n" }'  

En Perl:

 my %words; while (<>) { map { $words{lc $_} = 1 } split /\s/); } print scalar keys %words, "\n"; 

Utilisation des commandes bash / UNIX:

 sed -e 's/[[:space:]]\+/\n/g' $FILE | sort -fu | wc -l 

En utilisant uniquement les utilitaires Unix standard:

 < somefile tr 'AZ[:blank:][:punct:]' 'az\n' | sort | uniq -c 

Si vous êtes sur un système sans Gnu tr , vous devrez remplacer " [:blank:][:punct:] " par une liste de tous les caractères d'espacement et de ponctuation que vous souhaitez considérer comme séparateurs de mots , plutôt qu'une partie d'un mot, par exemple, " \t.,; ".

Si vous souhaitez que la sortie soit sortingée par ordre décroissant de fréquence, vous pouvez append " | sort -r -n " à la fin de celle-ci.

Notez que cela produira également un nombre non significatif de jetons d'espacement; Si cela vous préoccupe, vous pouvez utiliser sed pour filtrer les lignes vides.

Voici un one-liner de Perl:

 perl -lne '$h{lc $_}++ for split /[\s.,]+/; END{print scalar keys %h}' file.txt 

Ou pour lister le compte pour chaque article:

 perl -lne '$h{lc $_}++ for split /[\s.,]+/; END{printf "%-12s %d\n", $_, $h{$_} for sort keys %h}' file.txt 

Cela tente de gérer la ponctuation pour que “foo”. est compté avec “foo” alors que “do not” est traité comme un seul mot, mais vous pouvez ajuster la regex à vos besoins.

Simplement (52 coups):

 perl -nE'@w{map lc,split/\W+/}=();END{say 0+keys%w}' 

Pour les anciennes versions de perl (55 coups):

 perl -lne'@w{map lc,split/\W+/}=();END{print 0+keys%w}' 

Une version plus courte en Python:

 print len(set(w.lower() for w in open('filename.dat').read().split())) 

Lit le fichier entier en mémoire, le divise en mots à l’aide d’espaces, convertit chaque mot en minuscule, crée un ensemble (unique) à partir des mots minuscules, les compte et imprime la sortie.

Aussi possible en utilisant un seul liner:

 python -c "print len(set(w.lower() for w in open('filename.dat').read().split()))" 

Voici un awk oneliner.

 $ gawk -v RS='[[:space:]]' 'NF&&!a[toupper($0)]++{i++}END{print i}' somefile 
  • «NF» signifie «s’il y a un personnage».
  • ‘! a [topuuer [$ 0] ++]’ signifie ‘afficher uniquement les mots uniq’.