tr: Usage, Options & Common CI Errors
tr maps or removes individual characters as text streams through it.
tr is the simplest character-level transformer: uppercase a string, strip carriage returns, squeeze whitespace. It only reads stdin - it does not take a filename - which trips up newcomers.
What it does
tr reads stdin, translates characters in set1 to set2 (or deletes/squeezes them), and writes stdout. It operates on single characters, not strings or patterns.
Common usage
echo "hi" | tr 'a-z' 'A-Z' # -> HI
tr -d '\r' < dos.txt > unix.txt # strip CR (CRLF -> LF)
echo "a b" | tr -s ' ' # squeeze repeated spaces
tr -cd '[:alnum:]' < in > out # keep only alphanumerics
echo "$LIST" | tr ',' '\n' # commas to newlinesOptions
| Flag | What it does |
|---|---|
| -d | Delete characters in set1 |
| -s | Squeeze repeats of set1 into one |
| -c / -C | Complement set1 (everything not in it) |
| [:class:] | Character classes like [:alnum:], [:space:] |
| a-z | Character ranges |
Common errors in CI
tr only reads stdin - tr ... file.txt treats file.txt as a second set, not a file; redirect with < file or pipe in. "tr: range-endpoints of \u2018a-Z\u2019 are in reverse collating sequence order" comes from a locale-confused range; use LC_ALL=C or explicit [:upper:]/[:lower:] classes. A common need is stripping \r from CRLF files so downstream parsing does not see stray carriage returns.