Obtenez le nombre d'occurrences de mots dans les fichiers texte de tous les mots et triez la sortie d'impression

28

J'avais une commande qui fonctionnerait à travers un fichier texte, compterait toutes les occurrences des mots et l'imprimerait comme ceci:

user@box $˜ magic-command-i-forgot | with grep | and awk | sort ./textfile.txt
66: the
54: and
32: I
16: unix
12: bash
5:  internet
3:  sh
1: GNU/Linux

Il ne recherche donc pas ligne par ligne, mais mot par mot, et il le fait pour tous les mots, pas seulement pour 1 mot. Je l'avais trouvé quelque part sur les internets il y a longtemps, mais je ne peux pas le trouver ou m'en souvenir ..

Kusalananda
la source

Réponses:

33

J'utiliserais trau lieu de awk :

echo "Lorem ipsum dolor sit sit amet et cetera." | tr '[:space:]' '[\n*]' | grep -v "^\s*$" | sort | uniq -c | sort -bnr
  • tr remplace simplement les espaces par des sauts de ligne
  • grep -v "^\s*$" coupe les lignes vides
  • sort préparer comme entrée pour uniq
  • uniq -c compter les occurrences
  • sort -bnr trie dans l'ordre inverse numérique tout en ignorant les espaces

sensationnel. il s'est avéré être une excellente commande pour compter les jurons par ligne

trouver . -name "* .py" -exec cat {} \; | tr '[: espace:]' '[\ n *]' | grep -v "^ \ s * $" | trier | uniq -c | sort -bnr | grep baise

seler
la source
Pourrait vouloir utiliser tr -spour gérer plusieurs espaces, en particulier lorsque vous rencontrez une indentation.
Arcege
@Arcege: Bon point. Bien que cela ne changera pas le résultat, il peut fixer un peu le script.
seler
-g( --general-numeric-sort) l'option de sortpeut être préférable dans certains cas. Par exemple sort -n, gardera 10\n1 4tel quel , en traitant 1 4comme 14, tandis que sort -gle traitera correctement comme 1 4\n10.
Skippy le Grand Gourou
belle commande, mérite vraiment un vote :)
Noor
@seler Je pense que vous pouvez rendre la partie grep et tr encore plus simple comme ci-dessous: echo "Lorem ipsum dolor sit sit amet et cetera." | tr ' ' '\n' | grep -v "^$" | sort | uniq -c | sort -bnrNotez que je suis un débutant, donc je peux me tromper, n'hésitez pas à le conseiller.
smc
8
  1. Divisez l'entrée en mots, un par ligne.
  2. Triez la liste résultante de mots (lignes).
  3. Écraser plusieurs occurrences.
  4. Trier par nombre d'occurrences.

Pour diviser l'entrée en mots, remplacez tout caractère que vous jugez être un séparateur de mots par une nouvelle ligne.

<input_file \
tr -sc '[:alpha:]' '[\n*]' | # Add digits, -, ', ... if you consider
                             # them word constituents
sort |
uniq -c |
sort -nr
Gilles 'SO- arrête d'être méchant'
la source
C'est une bonne réponse car elle peut gérer le cas où les mots sont directement à côté d'une ponctuation non mot que vous souhaitez ignorer.
David Grayson
5

Ne pas utiliser grep et awk mais cela semble faire ce que vous voulez:

for w in `cat maxwell.txt`; do echo $w; done|sort|uniq -c
  2 a
  1 A
  1 an
  1 command
  1 considered
  1 domain-specific
  1 for
  1 interpreter,
  2 is
  1 language.
  1 line
  1 of
Bram
la source
1
Cela ne fonctionnera pas si l'entrée contient des caractères génériques du shell (que vous devez ajouter set -f) et traite la ponctuation comme faisant partie des mots (ce qui peut être corrigé maladroitement en ajoutant des caractères de ponctuation à IFS- bonne chance en essayant de prendre en charge les jeux de caractères non ASCII). Ce ne sera pas bon avec des fichiers d'entrée très volumineux, car il stocke tout le fichier en mémoire ( sortc'est plus intelligent).
Gilles 'SO- arrête d'être méchant'
2

Je crois que tu veux quelque chose comme ça?

$ perl -n -e 'foreach ${k} (split(/\s+/)){++$h{$k}};END{foreach $l (keys(%h)){print "$h{$l}: ${l}\n"}}' /path/to/your/file | sort -n -k 1

bien sûr, vous pouvez faire de même avec awk:)

amitkr
la source
2

Utilisation de la awk/sort/uniqsolution:

awk '{for(w=1;w<=NF;w++) print $w}' ~/textFile.txt | sort | uniq -c | sort -nr
Prince John Wesley
la source
Beau! Cela a fonctionné parfaitement.
stidmatt
0
file=/home/stefan/ooxml1.txt
for word in $(sed 's/[^A-Za-z]/ /g' $file | tr " " "\n" | sort -u)
do
  echo -n "$word "
  grep -c $word $file
done | sort -k2 -n 

tri croissant après avoir divisé le fichier en mots.

Le grep simple trouvera fishdans fisheye, vous devez donc améliorer la commande grep pour empêcher les correspondances partielles.

Prend environ 3 secondes pour un fichier texte de 25k sur une machine de tous les temps, disque dur classique (IDE).

Pour les fichiers plus gros ou les opérations souvent effectuées, une approche de carte de hachage serait préférable, mais pour un travail rarement exécuté ou pour des fichiers plus petits uniquement, cela pourrait être suffisant.

Utilisateur inconnu
la source