Salta al contenuto principale

head e tail: l'inizio e la fine di un file

Inviato da tuxsa il

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

  • head stampa le prime 10 righe di ogni file indicato.
  • tail stampa le ultime 10 righe. Con l'opzione -f può 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.txt

Esempio 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
15

Senza 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
15

Si 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
3

Qui 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.csv

Esempio 5: contare i byte con -c

$ head -c 20 numeri.txt

Con -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
pere

Con -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/syslog

Il 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/syslog

Con -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
10

Esempio 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 3

Il 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 5 mostra le ultime 5 righe, tail -n +5 parte 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/log sono leggibili solo da root o da utenti di certi gruppi. Se vedi Permesso negato, serve sudo, 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 di tail -f è journalctl -f.
  • File binari: come per cat, mostrarli a schermo può riempire il terminale di caratteri illeggibili. Se succede, scrivi reset.

Riepilogo

ComandoCosa fa
head filePrime 10 righe
head -n 3 filePrime 3 righe
head -n -3 fileTutto tranne le ultime 3 righe
tail fileUltime 10 righe
tail -n 3 fileUltime 3 righe
tail -n +2 fileDalla seconda riga in poi (salta l'intestazione)
tail -f fileSegue il file in tempo reale
tail -F fileCome -f, resiste alla rotazione dei log
head -n 10 f | tail -n 3Righe dall'8 al 10