sort ordina le righe di un testo e uniq elimina quelle ripetute. Presi singolarmente sono utili; usati insieme formano una delle combinazioni più classiche del terminale, quella che permette di contare quante volte compare ogni elemento in un elenco o in un file di log.
Cos'è
sort significa "ordina" e uniq è l'abbreviazione di "unique", "unico". Entrambi fanno parte del pacchetto GNU coreutils e sono eseguibili (/usr/bin/sort e /usr/bin/uniq), presenti su qualsiasi distribuzione GNU/Linux.
Cosa fanno
sortlegge le righe di uno o più file, o dello standard input, e le stampa in ordine. Di default l'ordine è alfabetico, secondo le regole della lingua del sistema.uniqstampa le righe eliminando le ripetizioni, ma con una regola importante: toglie solo i duplicati adiacenti, cioè consecutivi. Per questo viene quasi sempre preceduto dasort, che porta vicine le righe uguali.
Nessuno dei due modifica i file di partenza: scrivono il risultato a schermo, o dove lo reindirizzi.
Come si usano
Sintassi base:
$ sort [opzioni] [file...]
$ uniq [opzioni] [file_in_ingresso [file_in_uscita]]Per gli esempi usiamo un file frutta.txt con dieci righe, in cui alcuni nomi si ripetono:
$ cat frutta.txt
mele
pere
banane
mele
arance
pere
mele
banane
pere
meleEsempio 1: ordinare con sort
$ sort frutta.txt
arance
banane
banane
mele
mele
mele
mele
pere
pere
pereCon -r (reverse) l'ordine è invertito:
$ sort -r frutta.txtEsempio 2: ordinare i numeri con -n
Di default i numeri sono ordinati come se fossero testo, cifra per cifra. Il file punti.txt contiene i valori 10, 9, 100, 25 e 2:
$ sort punti.txt
10
100
2
25
9
$ sort -n punti.txt
2
9
10
25
100Con -n (numeric) i valori sono confrontati come numeri, e l'ordine è quello che ci si aspetta.
Esempio 3: ordinare le dimensioni con -h
L'opzione -h (human-numeric) riconosce i suffissi come K, M e G, e va d'accordo con l'output di du -h:
$ du -sh * | sort -h
4,0K note.txt
120K relazione.pdf
2,3M intervista.mp3
1,1G videoEsempio 4: ordinare per colonna con -t e -k
Con -t si indica il carattere che separa i campi e con -k la colonna da usare come chiave. Nel file utenti.txt ogni riga ha un nome e un'età separati da due punti:
$ cat utenti.txt
mario:42
anna:35
luca:28
$ sort -t: -k2 -n utenti.txt
luca:28
anna:35
mario:42Il file è ordinato per età, cioè per il secondo campo, in senso numerico. Lo stesso metodo vale per i file di sistema: sort -t: -k3 -n /etc/passwd li ordina per identificativo utente.
Esempio 5: ordinare ed eliminare i duplicati con -u
$ sort -u frutta.txt
arance
banane
mele
pereL'opzione -u (unique) fa in un colpo solo ciò che si otterrebbe con sort | uniq.
Esempio 6: salvare il risultato sullo stesso file con -o
$ sort -o frutta.txt frutta.txtCon -o si può scrivere il risultato nel file di partenza in tutta sicurezza. Se invece usassi sort frutta.txt > frutta.txt, la shell svuoterebbe il file prima che sort lo legga, e perderesti tutto il contenuto: lo stesso errore visto per cat.
Esempio 7: uniq da solo non basta
Poiché uniq toglie solo le righe consecutive, sul file non ordinato non cambia nulla, perché nessuna riga è uguale alla precedente:
$ uniq frutta.txt
mele
pere
banane
mele
arance
pere
mele
banane
pere
meleDopo un ordinamento, invece, funziona come ci si aspetta:
$ sort frutta.txt | uniq
arance
banane
mele
pereEsempio 8: contare le ripetizioni con uniq -c
$ sort frutta.txt | uniq -c
1 arance
2 banane
4 mele
3 pereL'opzione -c (count) antepone a ogni riga il numero di volte in cui compariva.
Esempio 9: solo i duplicati o solo gli unici
$ sort frutta.txt | uniq -d
banane
mele
pere
$ sort frutta.txt | uniq -u
aranceCon -d (duplicates) si stampano le righe che compaiono più di una volta, una sola volta ciascuna; con -u (unique) solo quelle che compaiono una volta sola.
Esempio 10: la classifica delle frequenze
Aggiungendo un secondo sort, in senso numerico e inverso, si ottiene una classifica dall'elemento più frequente al meno frequente:
$ sort frutta.txt | uniq -c | sort -nr
4 mele
3 pere
2 banane
1 aranceÈ lo schema sort | uniq -c | sort -nr, da ricordare a memoria. Con head in coda si limita la classifica ai primi risultati. Per esempio, per sapere quali estensioni di file sono più diffuse nella tua cartella personale, puoi usare anche sed per isolare l'estensione:
$ find ~ -type f -name "*.*" | sed 's/.*\.//' | sort | uniq -c | sort -nr | head -n 3
412 txt
187 jpg
96 pdfEsempio 11: uso negli script
Unire due elenchi senza duplicati e trovare gli elementi presenti in entrambi:
#!/bin/bash
sort -u iscritti_a.txt iscritti_b.txt > iscritti_unione.txt
echo "Elementi unici: $(wc -l < iscritti_unione.txt)"
echo "Presenti in entrambi gli elenchi:"
{ sort -u iscritti_a.txt; sort -u iscritti_b.txt; } | sort | uniq -dNell'ultimo comando ogni elenco viene prima ripulito dai propri doppioni con sort -u. In questo modo una riga compare due volte solo se è presente in entrambi, e uniq -d la mostra.
Opzioni utili
Per sort:
-r: ordine inverso.-n: ordine numerico;-h: numerico con suffissi (K, M, G).-u: elimina le righe uguali dopo l'ordinamento.-t carattere: separatore dei campi;-k N: ordina in base al campo N.-f: ignora la differenza tra maiuscole e minuscole.-o file: scrive il risultato nel file indicato, anche se coincide con l'ingresso.-c: controlla se l'input è già ordinato, senza stampare nulla.-V: ordina i numeri di versione in modo naturale (1.2, 1.10);-M: per mese.
Per uniq:
-c: mostra quante volte compare ogni riga.-d: solo le righe ripetute;-u: solo quelle non ripetute.-i: ignora maiuscole e minuscole nel confronto.-f N: salta i primi N campi nel confronto.
Attenzione a
uniqvuole l'input ordinato: senzasorta monte, i duplicati non adiacenti non vengono rimossi.- L'ordine dipende dalla lingua del sistema: con le impostazioni italiane o inglesi
sortnon distingue chiaramente maiuscole e minuscole e trascura la punteggiatura;LC_ALL=C sort fileusa invece l'ordine puro dei caratteri, con le maiuscole prima delle minuscole. Per script riproducibili,LC_ALL=Cè spesso la scelta più sicura. - I numeri sono testo: senza
-n, 100 viene prima di 2. - Mai
sort file > file: svuota il file di partenza. Usa-ooppure un file temporaneo. - Righe "quasi" uguali: spazi finali e ritorni a capo di tipo Windows (
^M) fanno apparire diverse righe che sembrano identiche. Concat -Ali scopri. sort -uouniq? Se ti basta eliminare i doppioni,sort -uè più breve. Se vuoi contare le ripetizioni o stampare solo duplicati o unici, serveuniq.- I campi con
-k: di default il separatore è il passaggio da spazio a carattere non spazio. Con file separati da virgole o altri simboli ricordati di indicare-t. - File molto grandi:
sortgestisce file più grandi della memoria usando file temporanei, ma lo spazio nella cartella/tmpdeve bastare.
Riepilogo
| Comando | Cosa fa |
|---|---|
sort file | Ordina le righe in ordine alfabetico |
sort -r file | Ordine inverso |
sort -n file | Ordine numerico |
sort -h | Ordine per dimensioni (K, M, G) |
sort -t: -k2 file | Ordina per il secondo campo, separato da due punti |
sort -u file | Ordina ed elimina i duplicati |
sort -o f f | Ordina scrivendo sullo stesso file |
sort file | uniq | Elimina i duplicati |
sort file | uniq -c | Conta le ripetizioni |
sort file | uniq -d | Mostra solo le righe ripetute |
sort | uniq -c | sort -nr | Classifica per frequenza |