tr Cheatsheet
tr command reference for translating, deleting, and squeezing characters, with character classes, escape sequences, case conversion, and pipeline recipes.
The tr command changes text one character at a time. It reads only from standard input, so you pipe text into it or redirect a file. Every example below behaves the same with GNU tr and with the Rust-based tr that ships with Ubuntu 25.10 and later.
Basic Syntax
Input comes from a pipe or a redirect, never a file argument.
| Command | Description |
|---|---|
tr SET1 SET2 | Replace each character in SET1 with the matching one in SET2 |
tr -d SET1 | Delete characters in SET1 |
tr -s SET1 | Squeeze repeated characters in SET1 to one |
tr -c SET1 SET2 | Act on characters NOT in SET1 (also -C, --complement) |
tr -t SET1 SET2 | Truncate SET1 to the length of SET2 first |
tr -ds SET1 SET2 | Delete SET1, then squeeze SET2 |
command | tr SET1 SET2 | Translate the output of another command |
tr SET1 SET2 < in.txt > out.txt | Read a file and write the result to a new one |
Translate Characters
Characters map by position; the last character of SET2 repeats if it is shorter.
| Command | Description |
|---|---|
echo 'linuxize' | tr 'lin' 'red' | Map l to r, i to e, n to d; prints reduxeze |
tr ' ' '_' | Replace spaces with underscores |
tr ':' '\n' | Replace colons with newlines |
tr '{}' '()' | Replace curly braces with parentheses |
tr 'a-f' 'A-F' | Ranges map in order |
echo 'abcde' | tr 'abcde' '12' | Short SET2 reuses its last character; prints 12222 |
echo 'abcde' | tr -t 'abcde' '12' | Only a and b change; prints 12cde |
Change Case
Convert, swap, or rotate letter case.
| Command | Description |
|---|---|
tr '[:lower:]' '[:upper:]' | Lowercase to uppercase |
tr '[:upper:]' '[:lower:]' | Uppercase to lowercase |
tr 'a-z' 'A-Z' | Convert ASCII lowercase letters to uppercase |
tr 'a-zA-Z' 'A-Za-z' | Swap case; Hello becomes hELLO |
tr 'A-Za-z' 'N-ZA-Mn-za-m' | ROT13; run it twice to get the original text |
Delete Characters
Remove every occurrence of the characters in SET1.
| Command | Description |
|---|---|
tr -d 'aeiou' | Delete the listed characters |
tr -d '[:digit:]' | Delete all digits |
tr -d '[:punct:]' | Delete punctuation |
tr -d '\r' < win.txt > unix.txt | Convert Windows line endings to Unix |
tr -d '\n' | Join all lines into one |
tr -d '[:blank:]' | Delete spaces and tabs, keep newlines |
tr -d '[:space:]' | Delete all whitespace, including newlines |
Keep Only (Complement)
-c flips SET1. Add \n to SET1 to keep line breaks.
| Command | Description |
|---|---|
echo 'tel 123-456' | tr -cd '[:digit:]' | Keep only digits; prints 123456 with no newline |
tr -cd '[:alnum:]\n' | Keep letters, digits, and newlines |
tr -cd '[:print:]\n' | Strip control characters and other non-printable bytes |
tr -c 'a-z\n' '_' | Replace everything except a-z and newlines with _ |
tr -cs '[:alnum:]' '\n' | Print one word per line |
Squeeze Repeats
-s collapses a run of the same character into one.
| Command | Description |
|---|---|
tr -s ' ' | Collapse repeated spaces |
tr -s '\n' | Remove blank lines between lines of text |
tr -s ' \n' | Squeeze spaces and newlines in one pass |
tr -s ' ' '_' | Translate spaces to _, then squeeze the _ runs |
echo 'hello' | tr -s 'a-z' | Squeeze any repeated lowercase letter; prints helo |
Character Classes
Quote character classes. When translating, SET2 accepts only [:lower:] or [:upper:], paired with the opposite class at the same position in SET1. With -ds, SET2 accepts any character class.
| Class | Matches |
|---|---|
[:alnum:] | Letters and digits |
[:alpha:] | Letters |
[:digit:] | Digits 0-9 |
[:lower:] | Lowercase letters |
[:upper:] | Uppercase letters |
[:space:] | Space, tab, newline, carriage return, vertical tab, form feed |
[:blank:] | Space and tab only |
[:punct:] | Punctuation |
[:print:] | Printable characters, including space |
[:graph:] | Printable characters, excluding space |
[:cntrl:] | Control characters |
[:xdigit:] | Hex digits 0-9, A-F, a-f |
Escapes and Repeats
Special characters and fill patterns inside a set.
| Syntax | Meaning |
|---|---|
\n | Newline |
\t | Tab |
\r | Carriage return |
\\ | Backslash |
\0 | NUL byte |
\NNN | Byte with octal value NNN (1 to 3 digits) |
[c*] | In SET2, repeat c until SET2 is as long as SET1 |
[c*n] | In SET2, n copies of c |
Common Pipelines
Practical combinations with other commands.
| Command | Description |
|---|---|
printf '%s\n' "$PATH" | tr ':' '\n' | One PATH directory per line |
tr '\0' '\n' < /proc/$$/environ | Print a NUL-separated file one entry per line |
tr '\n' ',' < list.txt | Join lines with commas (leaves a trailing comma) |
tr -dc 'A-Za-z0-9' < /dev/urandom | head -c 16; echo | Random 16-character string |
tr -cs '[:alpha:]' '\n' < file.txt | grep -v '^$' | sort | uniq -c | sort -rn | Count how often each word appears (case-sensitive) |
Troubleshooting
Quick checks for common tr errors and surprises.
| Issue | Check |
|---|---|
extra operand 'file.txt' | tr does not accept file names; use tr ... < file.txt |
extra operand with -d and two sets | -d takes one set; use -ds to delete and squeeze |
missing operand after 'x' | Translation needs SET1 and SET2; add SET2 or use -d |
Output file is empty after tr ... < f > f | The shell truncates f first; write to a temp file, then mv it |
A set starting with - is read as an option | Put the dash last ('_-') or add -- before the sets |
-c output has one extra character | The trailing newline is in the complement; add \n to SET1 |
| Accented letters turn into garbage | tr works on bytes; use sed for multibyte UTF-8 text |
Related Guides
Use these guides for full text-processing workflows.
| Guide | Description |
|---|---|
| tr Command in Linux | Full tr guide with examples |
| sed Find and Replace | Replace words and patterns |
| Bash String Manipulation | Change case and replace text inside the shell |
| cut Command in Linux | Extract fields after squeezing spaces |
| uniq Command in Linux | Count repeated lines and words |
| awk Command in Linux | Pattern-based field processing |