Comando head di Linux
Il comando head di Linux, come il comando tail di Linux, è uno degli strumenti essenziali della riga di comando. Fondamentalmente, il comando è usato per visualizzare l’inizio di un file (di testo) o per limitare l’output di un comando Linux a una determinata quantità.
Il comando head di Linux fa parte delle “GNU Core Utilities” (Coreutils), una raccolta di comandi di base della riga di comando. In linea con la filosofia Unix, i comandi usano un testo come formato universale di input e output. Le coreutils sono rilasciate con licenza open source e sono disponibili per una varietà di sistemi operativi diversi.
Perché si utilizza il comando head di Linux
Il comando head di Linux è usato per limitare l’output testuale sulla riga di comando. Ma perché questa opzione è utile o necessaria? Per rispondere alla domanda, diamo un’occhiata a come funziona in generale la riga di comando di Linux. La maggior parte dei comandi di Linux riceve o fornisce, rispettivamente, input o output testuali. L’origine o la destinazione di un comando possono essere costituite da:
- File: in particolare file di testo in formato ASCII. Di minore interesse qui sono i file binari come le immagini JPEG o i documenti Word.
- Input e output standard: testo che viene visualizzato o inserito dall’utente nel terminale.
- Le cosiddette “pipe” (in italiano “tubazioni”) sono concatenazioni di diversi comandi Linux. L’output testuale di un comando viene inoltrato come input testuale al comando successivo.
Consideriamo anche che i file possono contenere quantità incommensurabili di testo. Per esempio, un file di diversi gigabyte contiene miliardi di caratteri! Pertanto, spesso è utile limitare la quantità di testo visualizzato o visualizzare selettivamente solo alcune righe o porzioni di testo. Di seguito vi presentiamo una panoramica dei comandi Linux più comuni utilizzati per l’output di file di testo:
- CAT: visualizza l’intero file. L’output di grandi file sovraccarica la riga di comando.
- LESS: visualizza l’intero file pagina per pagina. Non è praticabile per i file di grandi dimensioni.
- HEAD: visualizza l’inizio di un file o limita l’output a un certo intervallo.
- TAIL: visualizza la fine di un file oppure limita l’output a un certo intervallo.
Se le spiegazioni che vi abbiamo fornito finora vi sembrano astratte, date un’occhiata agli esempi pratici qui sotto. Dovrebbero permettervi di capire i concetti esposti in termini più concreti.
Esecuzione del comando tail di Linux sulla riga di comando
L’esecuzione del comando tail di Linux avviene sulla riga di comando. Normalmente viene inserito il nome del comando seguito da parametri opzionali, completato infine dal nome o dal percorso di uno o più file. Per prima cosa, consideriamo la sintassi del caso generale:
head [opzioni] <file>
Senza opzioni, la sintassi più semplice del comando head di Linux è rappresentata dal seguente schema:
head <file>
In questo modo il comando head di Linux mostra le prime dieci righe del file specificato. Ciò permette di dare rapidamente un’occhiata all’inizio di un file, ottenendo spesso un’idea del contenuto.
Nell’uso quotidiano, il comando head di Linux è spesso combinato con l’opzione '-n'. Aggiungendo un numero in fondo si definisce quante linee devono essere visualizzate. Vediamo due esempi. Con la sintassi indicata di seguito viene visualizzata solo la prima riga di un file:
head -n 1 <file>
Possiamo usare lo stesso schema per visualizzare le prime 100 righe di un file:
head -n 100 <file>
Opzioni del comando head di Linux
In base alla convenzione, il comando head di Linux è controllato da parametri opzionali. Nell’ambito delle Coreutils GNU, esiste una forma lunga per ogni opzione; per le opzioni più frequentemente usate è disponibile anche una forma breve, spesso storicamente determinata. Mostriamo qui una panoramica delle opzioni più utili:
Opzione (forma breve / forma lunga) | Spiegazione |
---|---|
-n / --lines | Limita l’output alle prime n righe/ sopprime l’output delle ultime n righe |
-c / --bytes | Limita l’output ai primi n byte / sopprime l’output degli ultimi n byte |
-q / --quiet, --silent | Evita la visualizzazione dei nomi dei file quando il comando viene usato con più file |
-v / --verbose | Forza la visualizzazione dei nomi dei file quando il comando viene usato con più file |
--help | Mostra informazioni ausiliarie del comando |
Negli esempi seguenti usiamo le opzioni nella forma abbreviata (‘-n’, invece di ‘--lines’, ecc.); leggendo anche altri documenti o esempi di codice, scoprirete che questo è l’uso di gran lunga più utilizzato.
Excursus: cosa si intende per righe e caratteri?
Prima di considerare gli esempi pratici, permetteteci qualche parola sulla terminologia. Cosa intendiamo in realtà quando parliamo di “righe” e “caratteri”? A livello puramente intuitivo, si può certamente dare una risposta a questa domanda. Ma nell’ambiente digitale strettamente regolamentato, abbiamo bisogno di saperlo esattamente.
Internamente, un file di testo è una singola stringa continua di caratteri. La fine di ogni riga è contrassegnata solamente da un carattere chiamato “interruzione di linea”. A seconda del sistema operativo, il carattere utilizzato può essere diverso, il che può portare ad alcune incongruenze. In Linux, il carattere “Linefeed” (‘LF’) indica l’interruzione di riga.
Quando si usa l’opzione ‘-c’ / ‘--bytes’, si presuppone che un byte corrisponda esattamente a un carattere. Questo funziona per il set di caratteri ASCII, ma può causare problemi in altre situazioni. Il set di caratteri Unicode ampiamente usato oggi è una codifica di caratteri “multibyte”. Per rappresentare un singolo carattere, possono essere utilizzati diversi byte. Se si elaborano file di testo Unicode con il comando head di Linux, possono verificarsi strani effetti collaterali. Per esempio, usando l’opzione ‘-c’, una vocale accentata (per esempio “à”) può diventare la vocale corrispondente (“a”).
Esempi di utilizzo del comando head di Linux
Per rendere concretamente comprensibili gli esempi che seguono, usiamo il testo inglese della Dichiarazione Universale dei Diritti Umani (“Universal Declaration of Human Rights”, UDHR). Con traduzioni in più di 460 lingue, è uno dei testi più tradotti nella storia dell’umanità. Scarichiamo il testo della dichiarazione con il comando cURL di Linux e salviamolo come file ‘udhr.txt’ sul desktop, eseguendo il seguente frammento di codice nella riga di comando:
curl https://www.unicode.org/udhr/d/udhr_eng.txt> ~/Desktop/udhr.txt
Utilizzare il comando head di Linux per visualizzare solo la prima riga
Del modello per l’output della prima riga di un file di testo abbiamo già parlato. Di seguito è riportata la sintassi riferita al nostro esempio concreto:
head -n 1 ~/Desktop/udhr.txt
L’output della prima riga è utile in particolare per generare il cosiddetto “shabang” dello script di un file, ovvero la sequenza che indica al sistema quale interprete utilizzare per eseguire lo script e il relativo percorso.
Utilizzare il comando head di Linux per visualizzare tutto tranne l’ultima riga
Come accade per la prima riga, il comando head di Linux può essere utilizzato anche per visualizzare l’intero testo tranne l’ultima riga. Per farlo, usiamo l’opzione ‘-n’ e anteponiamo all’argomento un segno meno:
head -n -1 ~/Desktop/udhr.txt
Combinare il comando head di Linux con il comando tail per visualizzare specifiche aree di testo
Ora, cosa succede se vogliamo visualizzare solo il preambolo dell’UDHR dalla riga 9 alla 18? Per farlo, utilizziamo il comando “gemello” del comando head di Linux. Se il comando head di Linux visualizza la parte iniziale di un file di testo, il comando tail visualizza la fine. Se combiniamo i due comandi con il simbolo della pipe ‘|’, possiamo estrapolare un’area definita da un testo:
head -n 18 ~/Desktop/udhr.txt | tail -n 10
È possibile, ad esempio, visualizzare solo una determinata riga. A tale scopo utilizziamo il comando tail con l’opzione ‘-n 1’. Per visualizzare, ad esempio, solo la riga 28 “Everyone has the right to life, liberty and the security of person.” sfruttiamo il seguente comando.
head -n 28 ~/Desktop/udhr.txt | tail -n 1
Come potete vedere, viene visualizzata l’intera riga. Per visualizzare solo la parte fino a “security”, aggiungiamo un’altra chiamata del comando head di Linux interponendo una “pipe”. Quindi utilizziamo l’opzione ‘-c’ e proviamo diversi valori come argomento fino a isolare esattamente la parte richiesta. In questo caso abbiamo bisogno solo dei primi 62 caratteri:
head -n 28 ~/Desktop/udhr.txt | tail -n 1 | head -c 62
Un metodo più intuitivo può essere quello di contare il numero di caratteri partendo dalla fine. Anche questo è possibile anteponendo all’argomento dell’opzione ‘-c’ un segno meno. L’output del comando rimane lo stesso:
head -n 28 ~/Desktop/udhr.txt | tail -n 1 | head -c -12
Infine, vogliamo eliminare gli spazi vuoti iniziali. Probabilmente avrete già indovinato come possiamo fare. Esatto, aggiungiamo un altro parametro del comando tail dotando l’argomento dell’opzione ‘-c’ di un segno più. Come accade per il segno meno del comando head di Linux, in questo modo invertiamo il significato dell’opzione: invece di limitare l’output agli ultimi cinque caratteri, limitiamo l’output a tutto ciò che resta dal quinto carattere iniziale in poi:
head -n 28 ~/Desktop/udhr.txt | tail -n 1 | head -c -12 | tail -c +6
Ora vi starete chiedendo se vale davvero la pena costruire un comando così complesso. O c’è un modo più semplice? Effettivamente questo è solo un esempio. L’operazione può essere risolta più elegantemente con il comando Sed. Per i file più grandi, tuttavia, il comando head di Linux è più rapido del comando Sed.
Filtrare l’output del comando head di Linux con il comando grep
Avete già visto come il comando head di Linux può essere combinato con il comando tail. Un’altra combinazione comunemente usata è quella con il comando grep per filtrare il testo da visualizzare. In questo modo possiamo limitare l’output alle righe che contengono il termine di ricerca. Delle prime trenta righe del testo dell’UDHR vengono visualizzate solo quelle che contengono la parola “Person”:
head -n 30 ~/Desktop/udhr.txt | grep person
Elaborare più file con il comando head di Linux
Finora abbiamo usato il comando head di Linux per elaborare un singolo file. Tuttavia, è possibile specificare più file nella stessa chiamata. Per farlo possiamo elencare esplicitamente diversi nomi di file o percorsi oppure possiamo specificare il contenuto di un’intera directory o una chiave di ricerca come argomento del comando. L’esempio riportato qui mostra quest’ultima soluzione con i file di configurazione presenti nella directory di sistema ‘/etc/’. I file possiedono l’estensione ‘.conf’ che indichiamo come chiave di ricerca digitando ‘*.conf’:
head -n 1 /etc/*.conf
Per nascondere la visualizzazione dei nomi dei file quando si elaborano più file, si usa l’opzione ‘-q’:
head -q -n 1 /etc/*.conf
Analogamente, possiamo usare l’opzione ‘-v’ per forzare la visualizzazione dei nomi dei file. Questo è utile se alla chiave di ricerca corrisponde un unico file.
head -v /etc/host*.conf
Elencare i cinque file modificati più di recente con il comando head di Linux
In Linux usiamo il comando ls per generare un elenco di file e directory. Con l’opzione ‘-t’, ordiniamo l’elenco in ordine decrescente in base alla data dell’ultima modifica. Inoltre, per limitare l’elenco a cinque voci, aggiungiamo un’altra chiamata del comando head di Linux:
ls -t | head -n 5
Generare un hash casuale di una data lunghezza con il comando head di Linux
Il comando Linux ‘sha512sum’ crea un hash con una lunghezza di 128 caratteri. Per confrontare due hash a colpo d’occhio, spesso non è necessario esaminare l’hash intero. Può essere sufficiente, per esempio, guardare solo i primi otto caratteri. Questo schema potrebbe suonarvi familiare e ricordarvi i commit di Git. A tal fine eseguiamo il comando head di Linux con l’opzione ‘-c’. Come fonte dei dati usiamo la funzione bash ‘$RANDOM’ che restituisce un numero casuale:
echo $RANDOM | sha512sum | head -c 8