Ordina e conta il numero di occorrenze di righe


145

Ho un Apachefile di log, access.logcome contare il numero di occorrenze di riga in quel file? per esempio il risultato di cut -f 7 -d ' ' | cut -d '?' -f 1 | tr '[:upper:]' '[:lower:]'è

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

il risultato che voglio è:

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 non so mai che uniqpotrebbe farlo ...
— Kokizzu,

Hai un esempio della linea nel registro, poiché penso che tutto ciò potrebbe essere fatto con Awk senza tutte le pipe.

va bene, il file di registro da 8,1 GB è stato elaborato in circa 2 minuti, ed è fatto per ora, non è più necessario: 3
— Kokizzu,

Risposte:


197
| sort | uniq -c

Come indicato nei commenti.

Il piping dell'output in sortorganizza l'output in ordine alfabetico / numerico.

Questo è un requisito perché uniqcorrisponde solo su linee ripetute, ad es

a
b
a

Se si utilizza uniqsu questo file di testo, verrà restituito quanto segue:

a
b
a

Questo perché i due asono separati da b- non sono linee consecutive. Tuttavia, se prima si ordinano i dati in ordine alfabetico, come prima cosa

a
a
b

Quindi uniqrimuoverà le righe ripetute. L' -copzione uniqconta il numero di duplicati e fornisce l'output nel modulo:

2 a
1 b

Riferimenti:


1
Benvenuti in Unix e Linux :) Non esitate a aggiungere ulteriori dettagli alla vostra risposta e spiegare perché e come funziona;)
— John WH Smith,

1
printf '%s\n' ①.php ②.php | sort | uniq -cmi dà2 ①.php
— Stéphane Chazelas il

@ StéphaneChazelas Quello è perché il printf stampaphp\nphp

4
@Jidder, no, è perché ①.phpordina lo stesso che ②.phpnel mio locale perché nessun ordine di ordinamento è definito per quelli ①e il ②carattere nel mio locale. Se si desidera unici valori per tutti i valori di byte (ricordate i percorsi dei file non sono necessariamente di testo), allora avete bisogno di correggere la versione locale C: | LC_ALL=C sort | LC_ALL=C uniq -c.
— Stéphane Chazelas,

2
Per ordinare il file di conteggio risultante, dovresti considerare di aggiungere "sort -nr" come @ eduard-florinescu risponde di seguito.
— Lluís Suñol,

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

La risposta accettata è quasi completa, potresti voler aggiungere un extra sort -nralla fine per ordinare i risultati con le righe che si verificano più spesso per prime

opzioni uniq :

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

opzioni di ordinamento :

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

Nel caso particolare le linee che stai ordinando sono numeri, devi usare sort -grinvece di sort -nr, vedi commento


3
Grazie mille per avermi fatto conoscere l' -nopzione.
— Sigur,

2
Grande risposta, ecco quello che io uso per ottenere un numero di parole di file con frasi: tr ' ' '\n' < $FILE | sort | uniq -c | sort -nr > wordcount.txt. Il primo comando sostituisce gli spazi con newline, consentendo al resto del comando di funzionare come previsto.
— Bar,

2
Usando le opzioni sopra ottengo "1" prima di "23344". Utilizzando sort -grinvece risolve questo. -g: confronta in base al valore numerico generale (anziché -n: confronta in base al valore numerico della stringa).
— Peter Jaric,

@PeterJaric Grande cattura e molto utile da sapere, -grma penso che l'output di uniq -csarà tale che sort -nrfunzionerà come previsto
— Eduard Florinescu

3
In realtà, quando i dati sono numeri, -grfunziona meglio. Prova questi due esempi, che differiscono solo per i flag g e n: echo "1 11 1 2" | tr ' ' '\n' | sort | uniq -c | sort -nre echo "1 11 1 2" | tr ' ' '\n' | sort | uniq -c | sort -gr. Il primo ordina in modo errato, ma non il secondo.
— Peter Jaric,

9

Puoi usare un array associativo su awk e poi -optionally- sort :

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

produzione:

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

Come valuteresti il ​​numero di occorrenze mentre la pipe invia dati?
— user123456
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.