Terminal · intermediate
Character translation with tr
tr reads standard input and translates, deletes, or squeezes characters according to two character sets, then writes the result to standard output.
Why it matters
It is efficient for character-level normalization but cannot express word, field, or general substring replacements.
Mental model
How to reason about character translation with tr
Examine each input character independently, map or remove it according to membership and position in a set, and optionally collapse repeated output characters.
Analogy
It is a letter-by-letter substitution wheel: every symbol is handled independently, with no awareness of surrounding words.
Examples
See the boundary, not just the happy path
Worked example · Portable lowercase conversion
printf '%s' 'READY' | tr '[:upper:]' '[:lower:]'The named character classes request uppercase-to-lowercase translation according to the active locale.
Worked example · Squeeze repeated whitespace
printf 'a b\n' | tr -s '[:space:]' ' 'Translation maps whitespace characters to spaces and -s collapses each run of repeated output spaces to one.
Useful contrast · Not substring replacement
tr 'cat' 'dog'This maps individual characters c→d, a→o, and t→g; it does not replace occurrences of the word cat with dog.
Common mistakes
Misconceptions to remove early
Passing a filename as an input operand
Standard tr reads stdin and does not take an input filename operand, so use redirection or a pipeline.
Using bracket ranges without considering locale
Character range behavior can depend on collation; named classes better express categories such as upper and lower case.
Quick check
Can you predict the result?
1. Does tr 'ab' 'xy' replace the string ab as one unit?
- • No; it independently maps a to x and b to y.
- • Yes; only the complete substring ab changes.
- • No; tr can only delete characters.
2. What does tr -s do?
Keep building