<Precedenti | Contenuti | Succ.>
sorta
. sorta Il programma ordina il contenuto dell'input standard, o di uno o più file specificati sulla riga di comando, e invia i risultati all'output standard. Utilizzando la stessa tecnica che abbiamo utilizzato con gatto, possiamo dimostrare l'elaborazione dell'input standard direttamente dalla tastiera:
[io@linuxbox~]$ ordina > foo.txt
cba
[io@linuxbox~]$ cat foo.txt
abc
[io@linuxbox~]$ ordina > foo.txt
cba
[io@linuxbox~]$ cat foo.txt
abc
Dopo aver inserito il comando, digitiamo le lettere “c”, “b” e “a”, seguite ancora una volta da Ctrl-d per indicare la fine del file. Quindi visualizziamo il file risultante e vediamo che le righe ora appaiono ordinate.
Dal sorta può accettare più file sulla riga di comando come argomenti, è possibile unire più file in un unico insieme ordinato. Ad esempio, se avessimo tre file di testo e volessimo combinarli in un unico file ordinato, potremmo fare qualcosa del genere:
ordina file1.txt file2.txt file3.txt > elenco_ordinato_finale.txt
ordina file1.txt file2.txt file3.txt > elenco_ordinato_finale.txt
sort offre diverse opzioni interessanti. Ecco un elenco parziale:
Tabella 20-1: Opzioni di ordinamento comuni
Opzione | Opzione lunga | Descrizione |
-b | --ignora-spazi-iniziali | Per impostazione predefinita, l'ordinamento viene eseguito su |
tutta la linea, a partire dalla | ||
primo carattere della riga. Questo | ||
l'opzione fa sì che l'ordinamento ignori | ||
spazi iniziali nelle linee e | ||
calcola l'ordinamento in base al primo | ||
carattere non spazio vuoto su | ||
linea. | ||
-f | --ignora-caso | Rende l'ordinamento non sensibile alle maiuscole/minuscole. |
-n | --ordinamento-numerico | Esegue l'ordinamento in base alla valutazione numerica di una stringa. L'utilizzo di questa opzione consente di eseguire l'ordinamento su valori numerici anziché alfabetici. |
-r | --inversione | Ordina in ordine inverso. I risultati sono in |
discendente piuttosto che ascendente | ||
ordine. | ||
-k | --chiave=field1[,field2] | Ordina in base a un campo chiave situato |
da field1 a field2 piuttosto che la | ||
l'intera linea. Vedi la discussione qui sotto. | ||
-m | --unisci | Tratta ogni argomento come il nome |
di un file preordinato. Unisci più | ||
file in un unico risultato ordinato | ||
senza eseguire alcuna operazione aggiuntiva | ||
ordinamento. | ||
-o | --uscita=filetto | Invia output ordinato a filetto piuttosto |
rispetto all'output standard. | ||
-t | --separatore di campo=serbatoio | Definisci il separatore di campo |
carattere. Per impostazione predefinita i campi sono | ||
separati da spazi o tabulazioni. |
Sebbene la maggior parte delle opzioni sopra siano abbastanza autoesplicative, alcune non lo sono. Per prima cosa, diamo un'occhiata a -n opzione, utilizzata per l'ordinamento numerico. Con questa opzione, è possibile ordinare i valori in base ai valori numerici. Possiamo dimostrarlo ordinando i risultati dell' du comando per determinare i maggiori utilizzatori di spazio su disco. Normalmente, il du il comando elenca i risultati di un riepilogo in ordine di percorso:
[io@linuxbox~]$ du -s /usr/share/* | testa
252 /usr/share/aclocal
96 /usr/share/acpi-support
8 /usr/share/adduser
196 /usr/share/alacarte
344 /usr/share/alsa
8 /usr/share/alsa-base 12488 /usr/share/anthy
8 /usr/share/apmd
21440 /usr/share/app-install
48 /usr/share/application-registry
[io@linuxbox~]$ du -s /usr/share/* | testa
252 /usr/share/aclocal
96 /usr/share/acpi-support
8 /usr/share/adduser
196 /usr/share/alacarte
344 /usr/share/alsa
8 /usr/share/alsa-base 12488 /usr/share/anthy
8 /usr/share/apmd
21440 /usr/share/app-install
48 /usr/share/application-registry
In questo esempio, inoltriamo i risultati in capo Per limitare i risultati alle prime dieci righe, possiamo produrre un elenco ordinato numericamente per mostrare i dieci maggiori consumatori di spazio in questo modo:
[io@linuxbox~]$ du -s /usr/condividi/* | sort -nr | Testa
509940 /usr/share/locale-langpack
242660 /usr/share/doc
197560 /usr/share/fonts
179144 /usr/share/gnome
146764 /usr/share/myspell
144304 /usr/share/gimp
135880 /usr/share/dict
76508 /usr/share/icons
68072 /usr/share/apps
62844 /usr/share/foomatic
[io@linuxbox~]$ du -s /usr/condividi/* | sort -nr | Testa
509940 /usr/share/locale-langpack
242660 /usr/share/doc
197560 /usr/share/fonts
179144 /usr/share/gnome
146764 /usr/share/myspell
144304 /usr/share/gimp
135880 /usr/share/dict
76508 /usr/share/icons
68072 /usr/share/apps
62844 /usr/share/foomatic
Utilizzando il -nr opzioni, produciamo un ordinamento numerico inverso, con i valori più grandi che compaiono per primi nei risultati. Questo ordinamento funziona perché i valori numerici si trovano all'inizio di ogni riga. Ma cosa succede se vogliamo ordinare un elenco in base a un valore trovato all'interno della riga? Ad esempio, i risultati di un ls -l:
[io@linuxbox~]$ ls -l /usr/bin | testa
Totale 152948
-rwxr-xr-x | 1 | radice | radice | 34824 | 2016-04-04 | 02:42 | [ |
-rwxr-xr-x | 1 | radice | radice | 101556 | 2007-11-27 | 06:08 | a2p |
-rwxr-xr-x | 1 | radice | radice | 13036 | 2016-02-27 | 08:22 | collegare |
-rwxr-xr-x | 1 | radice | radice | 10552 | 2007-08-15 | 10:34 | acpi |
-rwxr-xr-x | 1 | radice | radice | 3800 | 2016-04-14 | 03:51 | acpi_fakekey |
-rwxr-xr-x | 1 | radice | radice | 7536 | 2016-04-19 | 00:19 | acpi_listen |
-rwxr-xr-x | 1 | radice | radice | 3576 | 2016-04-29 | 07:57 | aggiungi parte |
-rwxr-xr-x | 1 | radice | radice | 20808 | 2016-01-03 | 18:02 | indirizzo2riga |
-rwxr-xr-x | 1 | radice | radice | 489704 | 2016-10-09 | 17:02 | adept_batch |
Ignorando, per il momento, che ls possiamo ordinare i risultati in base alla dimensione, potremmo usare sorta per ordinare questo elenco anche in base alla dimensione del file:
[io@linuxbox~]$ ls -l /usr/bin | sort -nr -k 5 | head
-rwxr-xr-x | 1 | radice | radice | 8234216 | 2016-04-07 | 17:42 | inkscape |
-rwxr-xr-x | 1 | radice | radice | 8222692 | 2016-04-07 | 17:42 | vista inchiostro |
-rwxr-xr-x | 1 | radice | radice | 3746508 | 2016-03-07 | 23:45 | GIMP-2.4 |
-rwxr-xr-x | 1 | radice | radice | 3654020 | 2016-08-26 | 16:16 | Quanta |
-rwxr-xr-x | 1 | radice | radice | 2928760 | 2016-09-10 | 14:31 | gdbtui |
-rwxr-xr-x | 1 | radice | radice | 2928756 | 2016-09-10 | 14:31 | gdb |
-rwxr-xr-x | 1 | radice | radice | 2602236 | 2016-10-10 | 12:56 | rete |
-rwxr-xr-x | 1 | radice | radice | 2304684 | 2016-10-10 | 12:56 | cliente |
-rwxr-xr-x | 1 | radice | radice | 2241832 | 2016-04-04 | 05:56 | attitudine |
-rwxr-xr-x | 1 | radice | radice | 2202476 | 2016-10-10 | 12:56 | smbcacls |
Molti usi di sorta comportano l'elaborazione di dati tabulari, come i risultati del ls comando sopra. Se applichiamo la terminologia del database alla tabella sopra, diremmo che ogni riga è un record e che ogni record è costituito da più campi, come gli attributi del file, il conteggio dei link, il nome del file, la dimensione del file e così via. sorta è in grado di elaborare singoli campi. In termini di database, siamo in grado di specificare uno o più campi chiave da usare come chiavi di ordinamentoNell'esempio sopra, specifichiamo il n e r opzioni per eseguire un ordinamento numerico inverso e specificare -k 5 fare sorta utilizzare il quinto campo come chiave per l'ordinamento.
. k l'opzione è molto interessante e ha molte funzionalità, ma prima dobbiamo parlare di come sorta definisce i campi. Consideriamo un file di testo molto semplice composto da una singola riga contenente il nome dell'autore:
William Shott
William Shott
Per impostazione predefinita, sorta vede questa riga come se avesse due campi. Il primo campo contiene i caratteri:
"Guglielmo"
e il secondo campo contiene i caratteri:
"Shotts"
ciò significa che i caratteri di spazio (spazi e tabulazioni) vengono utilizzati come delimitatori tra i campi e che i delimitatori vengono inclusi nel campo quando viene eseguito l'ordinamento.
Guardando di nuovo una linea dal nostro ls output, possiamo vedere che una riga contiene otto campi e che il quinto campo è la dimensione del file:
-rwxr-xr-x 1 root radice 8234216 2016/04/07 17:42 inkscape
-rwxr-xr-x 1 root radice 8234216 2016/04/07 17:42 inkscape
Per la nostra prossima serie di esperimenti, prendiamo in considerazione il seguente file contenente la cronologia di tre popolari distribuzioni Linux rilasciate dal 2006 al 2008. Ogni riga del file ha tre campi: il nome della distribuzione, il numero di versione e la data di rilascio nel formato MM/GG/AAAA:
SUSE | 10.2 | 12/07/2006 |
Fedora | 10 | 11/25/2008 |
SUSE | 11.0 | 06/19/2008 |
Ubuntu | 8.04 | 04/24/2008 |
Fedora | 8 | 11/08/2007 |
SUSE | 10.3 | 10/04/2007 |
Ubuntu | 6.10 | 10/26/2006 |
Fedora | 7 | 05/31/2007 |
Ubuntu | 7.10 | 10/18/2007 |
Ubuntu | 7.04 | 04/19/2007 |
SUSE | 10.1 | 05/11/2006 |
Fedora | 6 | 10/24/2006 |
Fedora | 9 | 05/13/2008 |
Ubuntu | 6.06 | 06/01/2006 |
Ubuntu | 8.10 | 10/30/2008 |
Fedora | 5 | 03/20/2006 |
Utilizzando un editor di testo (forse vim), inseriremo questi dati e nomineremo il file risultante di- tros.txt.
Ora proveremo a ordinare il file e osserveremo i risultati:
[io@linuxbox | ~]$ | ordina distros.txt |
Fedora 10 | 11/25/2008 | |
Fedora 5 | 03/20/2006 | |
Fedora 6 | 10/24/2006 | |
Fedora 7 | 05/31/2007 | |
Fedora 8 | 11/08/2007 | |
Fedora 9 | 05/13/2008 | |
SUSO 10.1 | 05/11/2006 | |
SUSO 10.2 | 12/07/2006 | |
SUSO 10.3 | 10/04/2007 | |
SUSO 11.0 | 06/19/2008 | |
Ubuntu 6.06 | 06/01/2006 | |
Ubuntu 6.10 | 10/26/2006 | |
Ubuntu 7.04 | 04/19/2007 | |
Ubuntu 7.10 | 10/18/2007 | |
Ubuntu 8.04 | 04/24/2008 | |
Ubuntu 8.10 | 10/30/2008 |
Beh, ha funzionato per lo più. Il problema si verifica nell'ordinamento dei numeri di versione di Fedora. Poiché un "1" precede un "5" nel set di caratteri, la versione "10" finisce in cima mentre la versione "9" finisce in fondo.
Per risolvere questo problema dovremo ordinare su più chiavi. Vogliamo eseguire un ordinamento alfabetico sul primo campo e poi un ordinamento numerico sul secondo campo. sorta consente
più istanze di -k opzione che consente di specificare più chiavi di ordinamento. Infatti, una chiave può includere un intervallo di campi. Se non viene specificato alcun intervallo (come nel caso dei nostri esempi precedenti), sorta utilizza una chiave che inizia con il campo specificato e si estende fino alla fine della riga. Ecco la sintassi per il nostro ordinamento multi-chiave:
[io@linuxbox | ~]$ | ordina --key=1,1 --key=2n distros.txt |
Fedora 5 | 03/20/2006 | |
Fedora 6 | 10/24/2006 | |
Fedora 7 | 05/31/2007 | |
Fedora 8 | 11/08/2007 | |
Fedora 9 | 05/13/2008 | |
Fedora 10 | 11/25/2008 | |
SUSO 10.1 | 05/11/2006 | |
SUSO 10.2 | 12/07/2006 | |
SUSO 10.3 | 10/04/2007 | |
SUSO 11.0 | 06/19/2008 | |
Ubuntu 6.06 | 06/01/2006 | |
Ubuntu 6.10 | 10/26/2006 | |
Ubuntu 7.04 | 04/19/2007 | |
Ubuntu 7.10 | 10/18/2007 | |
Ubuntu 8.04 | 04/24/2008 | |
Ubuntu 8.10 | 10/30/2008 |
Sebbene abbiamo utilizzato la forma lunga dell'opzione per chiarezza, -k 1,1 -k 2n sarebbe esattamente equivalente. Nella prima istanza dell'opzione chiave, abbiamo specificato un intervallo di campi da includere nella prima chiave. Poiché volevamo limitare l'ordinamento solo al primo campo, abbiamo specificato 1,1 che significa "inizia al campo uno e termina al campo uno". Nel secondo caso, abbiamo specificato 2n, il che significa che il campo 2 è la chiave di ordinamento e che l'ordinamento deve essere numerico. È possibile includere una lettera opzionale alla fine di uno specificatore di chiave per indicare il tipo di ordinamento da eseguire. Queste lettere opzionali sono le stesse delle opzioni globali per sorta programma: b (ignora gli spazi iniziali), n (ordinamento numerico), r (ordinamento inverso) e così via.
Il terzo campo del nostro elenco contiene una data in un formato scomodo per l'ordinamento. Sui computer, le date sono solitamente formattate in AAAA-MM-GG per facilitare l'ordinamento cronologico, ma le nostre sono nel formato americano MM/GG/AAAA. Come possiamo ordinare questo elenco in ordine cronologico?
Fortunatamente, sorta fornisce un modo. L'opzione chiave consente la specificazione di offset all'interno dei campi, quindi possiamo definire le chiavi all'interno dei campi:
[io@linuxbox~]$ ordina -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt
Fedora 10 11/25/2008
Ubuntu 8.10 10/30/2008
[io@linuxbox~]$ ordina -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt
Fedora 10 11/25/2008
Ubuntu 8.10 10/30/2008
SUSE | 11.0 | 06/19/2008 |
Fedora | 9 | 05/13/2008 |
Ubuntu | 8.04 | 04/24/2008 |
Fedora | 8 | 11/08/2007 |
Ubuntu | 7.10 | 10/18/2007 |
SUSE | 10.3 | 10/04/2007 |
Fedora | 7 | 05/31/2007 |
Ubuntu | 7.04 | 04/19/2007 |
SUSE | 10.2 | 12/07/2006 |
Ubuntu | 6.10 | 10/26/2006 |
Fedora | 6 | 10/24/2006 |
Ubuntu | 6.06 | 06/01/2006 |
SUSE | 10.1 | 05/11/2006 |
Fedora | 5 | 03/20/2006 |
Specificando -k 3.7 noi istruiamo sorta per utilizzare una chiave di ordinamento che inizia dal settimo carattere nel terzo campo, che corrisponde all'inizio dell'anno. Allo stesso modo, specifichiamo -k 3.1 e -k 3.4 per isolare le parti del mese e del giorno della data. Aggiungiamo anche n e r opzioni per ottenere un ordinamento numerico inverso. Il b è inclusa un'opzione per sopprimere gli spazi iniziali (i cui numeri variano da riga a riga, influenzando così il risultato dell'ordinamento) nel campo data.
Alcuni file non utilizzano tabulazioni e spazi come delimitatori di campo; ad esempio, /etc/passwd
file:
[io@linuxbox~]$ testa /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh
[io@linuxbox~]$ testa /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh
I campi in questo file sono delimitati da due punti (:), quindi come potremmo ordinare questo file utilizzando un campo chiave? sorta fornisce il -t opzione per definire il carattere separatore di campo. Per ordinare il passwd file sul settimo campo (shell predefinita dell'account), potremmo fare questo:
[io@linuxbox~]$ ordina -t ':' -k 7 /etc/passwd | testa
me:x:1001:1001:Me stesso,,,:/home/me:/bin/bash
[io@linuxbox~]$ ordina -t ':' -k 7 /etc/passwd | testa
me:x:1001:1001:Me stesso,,,:/home/me:/bin/bash
root:x:0:0:root:/root:/bin/bash dhcp:x:101:102::/nonexistent:/bin/false
gdm:x:106:114:Gnome Display Manager:/var/lib/gdm:/bin/false hplip:x:104:7:Utente del sistema HPLIP,,,:/var/run/hplip:/bin/false klog:x:103:104::/home/klog:/bin/false messagebus:x:108:119::/var/run/dbus:/bin/false polkituser:x:110:122:PolicyKit,,,:/var/run/PolicyKit:/bin/false Pulse:x:107:116:PulseAudio demone,,,:/var/run/pulse:/bin/false
root:x:0:0:root:/root:/bin/bash dhcp:x:101:102::/nonexistent:/bin/false
gdm:x:106:114:Gnome Display Manager:/var/lib/gdm:/bin/false hplip:x:104:7:Utente del sistema HPLIP,,,:/var/run/hplip:/bin/false klog:x:103:104::/home/klog:/bin/false messagebus:x:108:119::/var/run/dbus:/bin/false polkituser:x:110:122:PolicyKit,,,:/var/run/PolicyKit:/bin/false Pulse:x:107:116:PulseAudio demone,,,:/var/run/pulse:/bin/false
Specificando il carattere due punti come separatore di campo, possiamo ordinare in base al settimo campo.