head mostra le prime righe di un file e tail le ultime. Quando un file è lungo e ti interessa solo come comincia o come finisce, non serve aprirlo tutto: bastano questi due comandi, che sono anche tra i più usati per controllare i file di log.
Cos'è
head e tail in inglese significano "testa" e "coda", e fanno esattamente questo: leggono la testa o la coda di un file. Fanno parte del pacchetto GNU coreutils e sono due eseguibili (/usr/bin/head e /usr/bin/tail), presenti su qualsiasi distribuzione GNU/Linux.
Cosa fanno
headstampa le prime 10 righe di ogni file indicato.tailstampa le ultime 10 righe. Con l'opzione-fpuò restare in attesa e mostrare le righe nuove man mano che vengono scritte.
Entrambi leggono anche dallo standard input, quindi funzionano in coda ad altri comandi con la pipe |, e nessuno dei due modifica i file. Anche con file di molti gigabyte rispondono subito: tail, in particolare, parte dalla fine del file senza leggerlo tutto.
Come si usano
Sintassi base, identica per entrambi:
$ head [opzioni] [file...]
$ tail [opzioni] [file...]Per gli esempi usiamo un file di 15 righe, create con il comando seq, che stampa i numeri da 1 a 15:
$ seq 15 > numeri.txtEsempio 1: le prime e le ultime righe
$ head numeri.txt
1
2
3
4
5
6
7
8
9
10
$ tail numeri.txt
6
7
8
9
10
11
12
13
14
15Senza opzioni, entrambi mostrano 10 righe.
Esempio 2: scegliere quante righe con -n
$ head -n 3 numeri.txt
1
2
3
$ tail -n 3 numeri.txt
13
14
15Si può anche scrivere in forma abbreviata head -3 numeri.txt.
Esempio 3: tutte le righe tranne alcune
Con un numero negativo, head stampa tutto tranne le ultime righe indicate:
$ head -n -12 numeri.txt
1
2
3Qui il file ha 15 righe, ne escludiamo le ultime 12 e restano le prime 3. Funziona con la versione GNU, ma non con quella di altri sistemi come macOS.
Esempio 4: partire da una riga precisa con tail -n +N
Il segno più davanti al numero cambia il significato: tail -n +N stampa dalla riga N fino alla fine.
$ tail -n +14 numeri.txt
14
15È il modo classico per saltare la riga di intestazione di un file CSV:
$ tail -n +2 dati.csvEsempio 5: contare i byte con -c
$ head -c 20 numeri.txtCon -c (bytes) al posto delle righe vengono mostrati i primi, o con tail gli ultimi, N byte. Serve a sbirciare l'inizio di un file di cui non sai se è testo.
Esempio 6: più file insieme
Con più file, ogni blocco è preceduto da un'intestazione con il nome:
$ head -n 2 numeri.txt lista.txt
==> numeri.txt <==
1
2
==> lista.txt <==
mele
pereCon -q (quiet) le intestazioni spariscono; con -v compaiono sempre, anche con un solo file.
Esempio 7: seguire un file di log con tail -f
$ tail -f /var/log/syslogIl comando mostra le ultime righe e poi resta in attesa: ogni nuova riga scritta nel file compare subito a schermo. Per fermarlo premi Ctrl+C. È lo strumento di base per capire cosa sta succedendo a un servizio in tempo reale.
Per i log che vengono "ruotati" (rinominati e ricreati a intervalli regolari) è meglio -F:
$ tail -F /var/log/syslogCon -f si segue il file aperto, e se questo viene sostituito da uno nuovo, tail smette di mostrare le novità. Con -F si segue il nome, quindi dopo la rotazione il comando continua con il file nuovo, e attende anche se il file ancora non esiste.
Esempio 8: un intervallo di righe, combinando head e tail
Per estrarre le righe da 8 a 10, prendi le prime 10 con head e di queste le ultime 3 con tail:
$ head -n 10 numeri.txt | tail -n 3
8
9
10Esempio 9: in coda ad altri comandi
Combinati con la pipe, servono a limitare qualsiasi output lungo:
$ ls -lt | head -n 5
$ history | tail -n 10
$ dmesg | tail -n 20
$ du -s * | sort -nr | head -n 3Il primo mostra i cinque file modificati più di recente, il secondo gli ultimi dieci comandi digitati, il terzo gli ultimi messaggi del kernel, il quarto le tre cartelle più pesanti.
Esempio 10: uso negli script
#!/bin/bash
LOG="/var/log/syslog"
ULTIMA=$(tail -n 1 "$LOG")
echo "Ultima riga del log: $ULTIMA"
RIGHE=$(tail -n +2 dati.csv | wc -l)
echo "Righe di dati (intestazione esclusa): $RIGHE"Opzioni utili
-n N: numero di righe da mostrare (default 10).-c N: numero di byte invece delle righe.head -n -N: tutto tranne le ultime N righe.tail -n +N: dalla riga N alla fine del file.tail -f: segue il file e mostra le righe nuove.tail -F: come-f, ma segue il nome del file (utile con la rotazione dei log).tail -n 0 -f: segue il file mostrando solo le righe scritte da adesso in poi.-q/-v: nasconde o mostra sempre le intestazioni con il nome del file.
Attenzione a
- Il segno più o meno:
tail -n 5mostra le ultime 5 righe,tail -n +5parte dalla quinta riga. Un solo carattere cambia il risultato. - Righe, non parole: i due comandi contano le righe così come sono nel file. Una riga molto lunga conta per una.
- Per fermare
tail -f: serve Ctrl+C. Non si ferma da solo. - Permessi sui log: molti file in
/var/logsono leggibili solo da root o da utenti di certi gruppi. Se vediPermesso negato, servesudo, oppure aggiungere l'utente al gruppo giusto. - I log di sistema moderni: sulle distribuzioni con systemd molti messaggi non stanno in file di testo ma nel journal, che si legge con
journalctl. Il corrispondente ditail -fèjournalctl -f. - File binari: come per
cat, mostrarli a schermo può riempire il terminale di caratteri illeggibili. Se succede, scrivireset.
Riepilogo
| Comando | Cosa fa |
|---|---|
head file | Prime 10 righe |
head -n 3 file | Prime 3 righe |
head -n -3 file | Tutto tranne le ultime 3 righe |
tail file | Ultime 10 righe |
tail -n 3 file | Ultime 3 righe |
tail -n +2 file | Dalla seconda riga in poi (salta l'intestazione) |
tail -f file | Segue il file in tempo reale |
tail -F file | Come -f, resiste alla rotazione dei log |
head -n 10 f | tail -n 3 | Righe dall'8 al 10 |