tr: Translate Character Sets
tr replaces each character in SET1 with the matching character in SET2 as bytes stream through.
tr is a character-level translator, not a string replacer. Use it to change case, swap delimiters, or normalize characters.
What it does
tr SET1 SET2 reads stdin and replaces each occurrence of a character in SET1 with the character at the same index in SET2. It supports ranges like a-z and POSIX classes like [:upper:] and [:lower:]. tr only reads stdin; it takes no filename arguments.
Common usage
tr 'a-z' 'A-Z' < file.txt # lowercase to uppercase
tr '[:lower:]' '[:upper:]' < file.txt # same, via classes
echo "$PATH" | tr ':' '\n' # colons to newlines
tr '/' '_' <<< "feature/login" # slashes to underscoresOptions
| Item | What it does |
|---|---|
| SET1 SET2 | Map each char in SET1 to the same-index char in SET2 |
| a-z | Character range |
| [:upper:] / [:lower:] | POSIX character classes |
| -d | Delete characters in SET1 (see tr -d) |
| -s | Squeeze repeats (see tr -s) |
In CI
tr '/' '_' is a common way to sanitize a branch name into a safe artifact or tag name. Converting $PATH or a colon list to newlines with tr ':' '\n' makes it greppable.
Common errors in CI
tr reads only stdin, so tr a b file.txt silently treats file.txt as an extra (ignored) set, not input; redirect with < instead. If SET2 is shorter than SET1, the last char of SET2 is repeated to pad, which can map several characters to one unexpectedly. In non-C locales, a-z ranges may include accented letters; set LC_ALL=C for ASCII-only ranges.