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.