Transforming text streams, sanitising messy user input, and stripping unwanted control characters are everyday duties in Linux shell scripting and data processing pipelines. While heavy command-line utilities like sed or awk offer sophisticated regular expression parsing, using them for basic byte-level substitutions or stripping non-printable characters is often over-engineered. The tr (translate) command is a core Unix utility built specifically for fast character-level transformations. Designed to process standard input and stream to standard output, tr allows you to translate character sets, delete specific characters, and collapse repeating sequences in a single, lightning-fast execution.
Understanding How the tr Command Works
The tr utility operates exclusively on standard input (stdin) and emits results to standard output (stdout). Because it does not accept filenames directly as arguments, you must supply data to tr using pipes (|) or input redirection (<).
The standard syntax pattern is:
tr [options] SET1 [SET2]
The utility compares input bytes against SET1 and transforms them according to the specified options or matching positional characters in SET2.
Converting Case (Uppercase and Lowercase)
One of the most frequent uses of tr is standardising letter cases across strings, logs, or filenames:
To convert all lowercase letters to uppercase:
echo "linux terminal automation" | tr '[:lower:]' '[:upper:]'
Output: LINUX TERMINAL AUTOMATION
Conversely, to convert uppercase text to lowercase:
echo "DATA_PIPELINE_OUTPUT" | tr '[:upper:]' '[:lower:]'
Translating Specific Delimiters and Characters
You can substitute characters one-for-one based on position:
To convert a colon-delimited string (such as the system PATH variable) into space-separated or newline-separated values:
echo "$PATH" | tr ':' '\n'
Each colon is immediately replaced with a line break, formatting your PATH directories into a clean vertical list.
To replace all parentheses with square brackets:
echo "Sample (Config)" | tr '()' '[]'
Deleting Specific Characters with the -d Flag
To strip unwanted characters entirely from an input stream, use the delete option (-d):
To remove all carriage return (\r) symbols from Windows-formatted text files (converting DOS line endings to Unix format):
tr -d '\r' < windows_file.txt > unix_file.txt
To strip all numerical digits from a text string:
echo "ServerNode-0482-Production" | tr -d '[:digit:]'
Output: ServerNode--Production
Squeezing Repeating Characters with the -s Flag
When parsing command outputs (such as ps, df, or custom logs), multiple consecutive spaces can disrupt downstream column slicing utilities like cut. The squeeze (-s) flag collapses consecutive repeated instances of a character down to a single instance:
echo "Linux System Administration" | tr -s ' '
Output: Linux System Administration
To convert multiple blank lines into a single blank line across a configuration file:
tr -s '\n' < dirty_config.conf > clean_config.conf
Complementing Character Sets with the -c Flag
The complement (-c) flag inverts your selection, targeting every character except those declared in SET1:
To strip everything from a string except alphanumeric characters (purging punctuation and special symbols):
echo "User#498! @Admin$" | tr -cd '[:alnum:]'
Output: User498Admin
Essential tr Command Options and Character Classes
| Option / Class | Syntax Example | Functionality |
|---|---|---|
-d |
tr -d 'set' |
Deletes all occurrences of characters in SET1 |
-s |
tr -s ' ' |
Squeezes multiple consecutive occurrences down to one |
-c |
tr -c 'set' |
Targets the complement (all characters NOT in SET1) |
[:alnum:] |
tr '[:lower:]' '[:upper:]' |
POSIX class matching all letters and numbers |
[:alpha:] |
tr -d '[:alpha:]' |
POSIX class matching all alphabetical letters |
[:digit:] |
tr -d '[:digit:]' |
POSIX class matching all numerical digits 0–9 |
[:space:] |
tr -s '[:space:]' |
POSIX class matching all whitespace, tabs, and newlines |
Frequently Asked Questions
Why does “tr file.txt” fail with an error?
The tr command strictly reads from standard input (stdin) and cannot take file paths directly as arguments. Always pipe input into tr (cat file.txt | tr ...) or use file redirection (tr ... < file.txt).
Can tr translate multi-character words or strings?
No. tr operates purely on a 1-to-1 character and byte mapping basis. To replace whole words (e.g., replacing “cat” with “dog”), use the stream editor sed: sed 's/cat/dog/g'.
How do I generate random alphanumeric passwords using tr?
Combine /dev/urandom with tr -dc: head /dev/urandom | tr -dc 'A-Za-z0-9!@#$' | head -c 16; echo. This filters pseudorandom kernel bytes down to 16 alphanumeric characters instantly.