Comando tac in Linux: invertire righe e record, con esempi sui delimitatori
tac mostra i record di un file dall’ultimo al primo. Un record è una porzione separata dalle altre da un delimitatore; per impostazione predefinita il delimitatore è la nuova riga, quindi tac inverte l’ordine delle righe senza invertire i caratteri al loro interno.
È utile per partire dal fondo di un log o invertire una sequenza già esistente. Gli esempi usano GNU Coreutils: per creare i file dimostrativi prepara una cartella nuova con mkdir tac-demo && cd tac-demo e continua soltanto se entrambi i comandi riescono. Usa nomi nuovi per non sovrascrivere documenti da conservare.
Il nome è cat scritto al contrario. Con più file, tac mantiene l’ordine degli operandi ma inverte i record di ciascun file separatamente: non li unisce prima in un’unica sequenza da rovesciare. Senza file, oppure con l’operando -, legge lo standard input e invia il risultato allo standard output, normalmente il terminale.
Sintassi di base
tac [OPTION]... [FILE]...
OPTION e FILE sono segnaposto. Controlla tac --help e man tac sul sistema di destinazione: tac e le sue estensioni non sono disponibili in ogni ambiente. Racchiudi tra virgolette i nomi con spazi e usa -- prima dei file se un nome inizia con un trattino, per esempio tac -- ./-events.log. L’operando esatto - continua a indicare lo standard input.
Uso di base di tac
Invertire le righe di un file
Nella cartella dimostrativa crea events.log con printf 'inizio\ncontrollo\nfine\n' > events.log. Il comando seguente stampa fine, controllo e inizio, ciascuno su una riga. Non modifica il file sorgente e non aggiunge una nuova riga mancante alla fine dell’input.
tac events.log
Elaborare più file
Crea january.log con printf 'gennaio-1\ngennaio-2\n' > january.log e february.log con printf 'febbraio-1\nfebbraio-2\n' > february.log. L’output sarà, nell’ordine, gennaio-2, gennaio-1, febbraio-2 e febbraio-1. Il primo file rimane prima del secondo: tac non riordina i mesi né confronta le date.
tac january.log february.log
Invertire lo standard input
La pipe | passa l’output di printf a tac. Il risultato seguente è three, two e one su tre righe. Per un input non riposizionabile, come una pipe, GNU tac deve ricevere la fine dell’input prima di produrre l’ordine inverso e usa un file temporaneo; un flusso che continua per sempre non fornisce quel punto finale.
printf 'one\ntwo\nthree\n' | tac
Verificare il risultato dell’inversione
Questa prova non richiede file di input: printf produce tre righe terminate da nuova riga e tac ne cambia soltanto l’ordine. Le parole rimangono first, second e third, senza inversione dei caratteri.
printf 'first\nsecond\nthird\n' | tac
Esempio di output:
third
second
first
Questo risultato coincide con un ordine dal più recente al più vecchio solo se l’input era già disposto cronologicamente. Tac non interpreta i timestamp. Inoltre il delimitatore resta associato al record: con un input formato dai byte A\nB, senza nuova riga finale, GNU tac produce BA\n. Non inserisce un separatore fra B e A, perciò un file senza terminazione finale può dare un risultato visivamente inatteso.
Opzioni principali
| Opzione | Scopo |
|---|---|
-s STRING |
Usa STRING come delimitatore al posto della nuova riga. Senza -r viene trattato come stringa letterale. |
-b |
Associa il delimitatore all’inizio del record successivo, anziché alla fine del record precedente. |
-r |
Interpreta il delimitatore indicato con -s come espressione regolare, anziché stringa letterale. |
--help |
Mostra la guida della versione installata; --version ne indica la versione. |
Esempi pratici
Sfogliare un log partendo dal fondo
Per una prova crea application.log con printf 'avvio\nrichiesta\nchiusura\n' > application.log. Con la riga seguente, less riceve chiusura, richiesta e avvio in questo ordine; permette di navigare e cercare, e normalmente si chiude con q. Questa combinazione riguarda un input finito. Non sostituisce tail -f application.log per seguire nuove righe in tempo reale.
tac application.log | less
Usare un delimitatore personalizzato
Crea records.txt con printf 'A---B---C---' > records.txt. Il comando seguente produce C---B---A---, senza nuova riga finale: per impostazione predefinita ogni delimitatore resta in coda al record precedente. Per un formato che inizia ciascun record con il delimitatore, crea invece un file nuovo con printf '%s' '---A---B---C' > before.txt: tac -b -s '---' before.txt produce ---C---B---A. Scegli -b in base alla struttura reale dei dati, non come correzione generica dell’output.
tac -s '---' records.txt
Trovare l’ultima riga che contiene un errore
Prepara access.log con printf 'ERROR vecchio\nOK\nERROR recente\n' > access.log. grep -m 1 si ferma dopo la prima riga corrispondente nell’ordine inverso: l’output atteso è ERROR recente. Qui ERROR è cercato come testo maiuscolo; non significa automaticamente che il formato del log definisca quella voce come errore. Se non ci sono corrispondenze grep restituisce 1; un errore di lettura o di esecuzione va distinto dall’assenza di risultati.
tac access.log | grep -m 1 'ERROR'
tac e comandi correlati
| Comando | Ruolo principale | Quando usarlo |
|---|---|---|
tac |
Invertire l’ordine dei record esistenti | Leggere un file dal fondo |
cat |
Conservare l’ordine originale | Visualizzare e concatenare file |
tail |
Selezionare la parte finale | Mostrare le ultime righe, mantenendone l’ordine |
sort -r |
Ordinare in senso inverso secondo il confronto scelto | Riordinare i contenuti; non riprodurre semplicemente l’ordine iniziale al contrario |
Avvertenze importanti
Non è un comando di ordinamento
Tac cambia l’ordine dei record così come sono memorizzati. sort -r confronta invece le righe secondo locale e opzioni: non interpreta automaticamente ogni formato di data o numero. Nei log con eventi su più righe, come una traccia di errore, invertire le singole righe può separare il messaggio dalle sue righe di contesto. Scegli un delimitatore o uno strumento che conosca il formato se devi mantenere unito ciascun evento.
I flussi senza fine non sono adatti
GNU tac può cercare a ritroso in un normale file riposizionabile. Una pipe deve invece essere accumulata in un file temporaneo: il manuale GNU indica TMPDIR e, come destinazione predefinita, /tmp. Occorrono spazio e permessi adeguati; non presumere che tutto rimanga soltanto in memoria. Con tail -f file.log | tac la pipe resta aperta e non ottieni un monitoraggio inverso continuo. Anche una ricerca che termina al primo risultato non elimina la necessità di ricevere prima l’intera pipe.
Controllare delimitatori e stato della pipeline
Con -r, i metacaratteri del delimitatore hanno significato speciale: usa gli apici per evitare interpretazioni della shell e verifica il risultato su un piccolo esempio. In GNU un delimitatore vuoto, -s '', seleziona il byte NUL, non una stringa che separa ogni carattere. Per le pipeline Bash, lo stato finale normalmente viene dall’ultimo comando e può nascondere un errore di tac; set -o pipefail cambia questo criterio. Se grep o less chiudono prima la lettura, tac può però ricevere SIGPIPE, il segnale di una pipe senza lettori: valuta i singoli stati e gli errori, senza trattare ogni stato non zero come lo stesso problema. Non reindirizzare l’output sul file di input: > può troncarlo prima della lettura. Scrivi in un nuovo file e verifica il risultato.
FAQ
tac e sort -r sono equivalenti?
No. Tac inverte la sequenza esistente; sort -r confronta e riordina le righe secondo le opzioni e il locale. L’inversione dei record non garantisce un ordinamento per data.
Come faccio a invertire solo le ultime dieci righe?
Usa tail -n 10 FILE | tac, sostituendo FILE con il percorso corretto. Se il file ha meno di dieci righe, vengono considerate quelle disponibili. La pipeline seleziona la coda prima di invertirla; non segue le aggiunte successive.
tac può seguire un log in tempo reale?
Non come visualizzatore inverso continuo. Una pipe deve terminare prima di poter essere invertita; per seguire le nuove righe usa tail -f. Per un esame coerente di dati che cambiano, lavora su una copia stabile del log.
tac unisce tutti i file prima di invertirli?
No. Elabora ciascun file nell’ordine degli operandi e inverte separatamente i suoi record. Se concatenassi prima gli input in una sola pipe, l’inversione riguarderebbe invece l’intero flusso, con attesa della sua fine.




