Trier et compter le nombre d'occurrences de lignes


145

J'ai Apachelogfile, access.logcomment compter le nombre d'occurrence de ligne dans ce fichier? par exemple le résultat de cut -f 7 -d ' ' | cut -d '?' -f 1 | tr '[:upper:]' '[:lower:]'is

a.php
b.php
a.php
c.php
d.php
b.php
a.php

le résultat que je veux est:

3 a.php
2 b.php
1 d.php # order doesn't matter
1 c.php 

25
| sort | uniq -c
Costas

3
| LC_ALL=C sort | LC_ALL=C uniq -c
Stéphane Chazelas

ah je ne sais jamais qui uniqpourrait faire ça ..
Kokizzu

Avez-vous un exemple de la ligne dans le journal, car je pense que tout cela pourrait être fait avec awk sans tous les tuyaux.

c'est bon, fichier journal de 8,1 Go traité en 2 minutes environ, et c'est fait pour le moment, vous n'en
avez

Réponses:


197
| sort | uniq -c

Comme indiqué dans les commentaires.

Piping the output en sortorganise la sortie en ordre alphabétique / numérique.

Ceci est une exigence car les uniqcorrespondances uniquement sur des lignes répétées, c'est-à-dire

a
b
a

Si vous utilisez uniqsur ce fichier texte, il retournera ce qui suit:

a
b
a

C'est parce que les deux as sont séparés par le b- ils ne sont pas des lignes consécutives. Cependant, si vous triez d'abord les données dans l'ordre alphabétique, comme

a
a
b

Puis uniqsupprimera les lignes répétitives. L' -coption de uniqcompte le nombre de doublons et fournit une sortie sous la forme:

2 a
1 b

Références:


1
Bienvenue dans Unix et Linux :) N'hésitez pas à ajouter plus de détails à votre réponse et à expliquer pourquoi et comment cela fonctionne;)
John WH Smith

1
printf '%s\n' ①.php ②.php | sort | uniq -cme donne2 ①.php
Stéphane Chazelas

@ StéphaneChazelas C'est parce que les impressions printfphp\nphp

4
@Jidder, non, c'est parce que les triages sont ①.phples mêmes que ②.phpdans mes paramètres régionaux, car aucun ordre de tri n'est défini pour ceux-ci et le caractère dans mes paramètres régionaux. Si vous voulez uniques valeurs pour toutes les valeurs d'octet (souvenez - vous des chemins de fichiers ne sont pas nécessairement du texte), alors vous devez corriger les paramètres régionaux C: | LC_ALL=C sort | LC_ALL=C uniq -c.
Stéphane Chazelas

2
Afin de trier le fichier de comptage résultant, vous devriez envisager d'ajouter le "sort-nr" en tant que réponses @ eduard-florinescu ci-dessous.
Lluís Suñol

104
[your command] | sort | uniq -c | sort -nr

La réponse acceptée est presque terminée, vous pouvez ajouter un petit plus sort -nrà la fin pour trier les résultats avec les lignes qui apparaissent le plus souvent en premier.

options uniq :

-c, --count
       prefix lines by the number of occurrences

options de tri :

-n, --numeric-sort
       compare according to string numerical value
-r, --reverse
       reverse the result of comparisons

Dans le cas particulier où les lignes que vous triez sont des nombres, vous devez les utiliser sort -grau lieu de sort -nr, voir le commentaire


3
Merci beaucoup de me faire savoir à propos de l' -noption.
Sigur

2
Grande réponse, voici ce que j'utilise pour obtenir un wordcount de fichier avec des phrases: tr ' ' '\n' < $FILE | sort | uniq -c | sort -nr > wordcount.txt. La première commande remplace les espaces par des nouvelles lignes, permettant ainsi au reste de la commande de fonctionner comme prévu.
Bar

2
En utilisant les options ci-dessus, je reçois "1" avant "23344". Utiliser à la sort -grplace résout ce problème. -g: compare en fonction de la valeur numérique générale (au lieu de -n: compare en fonction de la valeur numérique de la chaîne).
Peter Jaric

@PeterJaric Excellente prise et très utile à connaître, -grmais je pense que le résultat de uniq -csera tel sort -nr
quel

3
En fait, lorsque les données sont des nombres, cela -grfonctionne mieux. Essayez ces deux exemples, ne différant que par les drapeaux g et n: echo "1 11 1 2" | tr ' ' '\n' | sort | uniq -c | sort -nret echo "1 11 1 2" | tr ' ' '\n' | sort | uniq -c | sort -gr. Le premier trie de manière incorrecte, mais pas le second.
Peter Jaric

9

Vous pouvez utiliser un tableau associatif sur awk puis, éventuellement, trier :

cat access.log  | awk ' { tot[$0]++ } END { for (i in tot) print tot[i],i } ' | sort

sortie:

1 c.php
1 d.php
2 b.php
3 a.php

Comment comptez-vous le nombre d'occurrences pendant que le canal envoie des données?
user123456
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.