Comando tr in Linux: convertire caratteri, eliminare CR e ridurre spazi ripetuti
tr legge dallo standard input e scrive sull’uscita standard, traducendo o eliminando caratteri oppure riducendo ripetizioni consecutive. Non accetta un nome di file come argomento di input: passa il contenuto con una pipe o con la redirezione <.
È un filtro per caratteri, non un motore di sostituzione di parole o espressioni regolari. Per trovare un testo in un contesto e sostituirlo, consulta la guida in inglese a sed. Classi, intervalli e testo multibyte richiedono attenzione all’implementazione e alle impostazioni locali.
Sintassi e ingresso dei dati
tr [OPTION] SET1 [SET2] < INPUTFILE
Questa riga è una notazione: sostituisci i segnaposto con opzioni, sequenze di caratteri e un percorso reale. Le sequenze indicano i caratteri da selezionare e, quando occorre, i loro sostituti; le opzioni vanno prima degli operandi. Il secondo operando serve nella traduzione, mentre una cancellazione semplice con -d richiede solo il primo.
La redirezione è gestita dalla shell: tr riceve i byte del file, non il suo percorso. Usa man tr per controllare le opzioni disponibili. Negli esempi ASCII seguenti LC_ALL=C si applica al processo tr e rende esplicito l’ambiente locale del filtro.
Esempi: maiuscole, ritorni a capo e spazi
Da minuscole a maiuscole
Questa prova non crea file; il risultato viene mostrato nel terminale:
printf '%s\n' hello | LC_ALL=C tr '[:lower:]' '[:upper:]'
L’output è HELLO, seguito da una nuova riga. Le classi [:lower:] e [:upper:] sono racchiuse fra apici perché la shell non deve interpretarle come pattern per nomi di file. Questa prova riguarda lettere ASCII; non dimostra una conversione completa delle lettere accentate in UTF-8.
Eliminare i caratteri di ritorno carrello
Prepara due file dimostrativi in una directory nuova con una shell compatibile con Bash. Se tr-demo esiste, scegli un altro nome: la creazione fallisce e il resto non parte. Gli apici conservano le barre inverse, che vengono poi interpretate da printf o tr secondo il rispettivo formato.
mkdir tr-demo && cd tr-demo && (
set -e
set -o noclobber
printf 'prima\r\nseconda\r\n' > windows-lines.txt
printf 'uno\040\040due\t\t tre\n' > notes.txt
LC_ALL=C tr -d '\r' < windows-lines.txt
)
Ottieni prima e seconda su due righe. In windows-lines.txt ogni fine riga contiene CRLF, cioè ritorno carrello \r seguito da nuova riga \n; il filtro elimina CR e conserva LF. Puoi verificarlo con LC_ALL=C tr -d '\r' < windows-lines.txt | cat -v: nell’output non compaiono i marcatori ^M che GNU cat mostra per i CR.
-d '\r' elimina tutti i CR del contenuto, anche se non sono subito prima di LF. Non usarlo indiscriminatamente su dati binari o quando quei caratteri hanno un significato. Il file originale non viene modificato. Rimani nella directory tr-demo per la prova successiva.
Ridurre gli spazi ripetuti
Il file notes.txt contiene due spazi fra uno e due, due tabulazioni dopo due e uno spazio prima di tre. La sequenza \040 usata nella preparazione rappresenta uno spazio:
LC_ALL=C tr -s ' ' < notes.txt
Fra uno e due resta uno spazio; le due tabulazioni rimangono entrambe. Per vederle, aggiungi | cat -T: il risultato è uno due^I^I tre. -s riduce ripetizioni dello stesso carattere selezionato, senza trasformare automaticamente tabulazioni e spazi in un unico tipo.
Se vuoi convertire le tabulazioni in spazi e poi comprimere gli spazi risultanti, usa LC_ALL=C tr -s '\t' ' ' < notes.txt: ottieni uno due tre. Se invece scrivi tr -s '[:blank:]', vengono ridotte separatamente le ripetizioni di tabulazione e di spazio: una tabulazione seguita da uno spazio resta una coppia di caratteri diversi. Evita di sostituire indiscriminatamente [:space:] con uno spazio quando devi mantenere le righe, perché quella classe comprende anche la nuova riga.
Risultato di una conversione per caratteri
Per convertire le lettere ASCII maiuscole in minuscole:
printf 'HELLO 123\n' | LC_ALL=C tr '[:upper:]' '[:lower:]'
Output atteso:
hello 123
Le cifre, lo spazio e la nuova riga non appartengono alla classe da convertire e rimangono invariati. Gli operandi non sono parole da cercare: printf 'cat\n' | LC_ALL=C tr 'cat' 'dog' produce dog perché associa separatamente c a d, a a o e t a g. Lo stesso filtro trasformerebbe tac in god, anche senza la parola cat nell’input.
Opzioni e sequenze di selezione
| Opzione o classe | Significato |
|---|---|
-d |
Elimina i caratteri selezionati dal primo operando. |
-s |
Riduce a una occorrenza le ripetizioni consecutive dello stesso carattere presente nell’ultimo operando, dopo eventuale traduzione o cancellazione. |
-c |
Seleziona il complemento del primo operando: i valori che non vi compaiono. Usa cautela fuori dagli ambienti a byte singolo. |
[:lower:] / [:upper:] |
Classi abbinate per la conversione fra minuscole e maiuscole, soggetta alle condizioni dell’implementazione e dell’ambiente locale. |
Per esempio, printf 'a1b2\n' | LC_ALL=C tr -cd '[:digit:]\n' produce 12 seguito da una nuova riga: -c inverte la selezione e -d elimina tutto ciò che non è una cifra o LF. Se ometti \n, vengono eliminate anche le interruzioni di riga.
Precauzioni: UTF-8, intervalli e file di uscita
Le sequenze di tr non sono espressioni regolari complete. In particolare, non usare una sintassi come [a-z] presumendo che abbia automaticamente il significato di una classe di una regex. Gli intervalli dipendono dalle regole previste nell’ambiente locale; per la conversione ASCII negli script usa un ambiente esplicito e verifica il risultato.
Il manuale GNU segnala che il supporto completo di tr riguarda ambienti sicuri a byte singolo, come C nei sistemi GNU. Impostare C rende prevedibile l’elaborazione dei byte, ma non trasforma tr in un filtro Unicode: un carattere UTF-8 può occupare più byte. Per conversioni linguistiche o sostituzioni multibyte usa uno strumento che supporti esplicitamente la codifica e prova i caratteri reali; anche sed va scelto e verificato secondo l’implementazione e l’ambiente locale.
Per salvare il file senza CR nella directory di prova puoi usare LC_ALL=C tr -d '\r' < windows-lines.txt > unix-lines.txt, scegliendo una destinazione nuova, poi controllare il successo del comando e cat -v unix-lines.txt. La redirezione può sovrascrivere un file esistente. Non usare lo stesso percorso per input e output: la shell può svuotarlo prima che tr lo legga. Conserva l’originale finché non hai verificato il risultato; il filtro non modifica direttamente il file in ingresso.
Domande frequenti
Posso passare direttamente un nome di file a tr?
No. Usa la redirezione, per esempio LC_ALL=C tr -d '\r' < windows-lines.txt, oppure una pipe. Un nome aggiunto alla riga di comando viene interpretato come operando di selezione o traduzione, oppure causa un errore: non viene aperto automaticamente come file di input.
Documentazione di riferimento
La pagina di manuale GNU di tr su man7 descrive le opzioni e i limiti di codifica della versione documentata. Il riferimento POSIX per tr specifica operandi, classi e trasformazioni.




