The Linux tr Command

The Linux tr Command

With echo ‘mississippi’ | tr -c ‘s’ ‘z’, the final z replaces the line break, so the prompt appears on the same line. I couldn’t resist digging into why tr treats that ending as part of the transformation.

Follow tr’s character transformation from standard input to standard output. Choose the operation by deciding which characters in the stream should change.

What the tr command changes

The Linux tr command reads characters from standard input and writes the transformed stream to standard output, so it can sit between commands in a pipe or read redirected file input. It can translate or delete individual characters, or squeeze repeated copies of selected characters.

Tr writes only to standard output, so save results to a separate file instead of redirecting into the input file.

TaskShapeEffect
Translatetr SET1 SET2Map selected characters to corresponding characters
Deletetr -d SET1Remove characters in SET1
Keep a settr -cd SET1Delete characters outside SET1
Squeezetr -s SET1Reduce repeated selected characters to one

What you need before running tr

The command takes one or two character sets after its options. In a translation, SET1 selects input characters and SET2 supplies their replacements in the same order.

tr [OPTION]... SET1 [SET2]

Quote bracket sets such as [:digit:] so the shell passes them to tr instead of expanding them as filename wildcards. Use [:blank:] for spaces and tabs, because [:space:] also includes line breaks.

Input redirection reads a file but does not edit it in place. GNU tr works on bytes, so input with multibyte characters needs care.

Use tr for common character tasks

Choose the operation by the characters you want to change, not by the file format. In each translation below, the first set selects input characters and the second set determines what replaces them.

GoalUseful form
Change casetr ‘[:lower:]’ ‘[:upper:]’
Remove digitstr -d ‘[:digit:]’
Keep digits and line breakstr -cd ‘[:digit:]\n’
Split at separatorstr -cs ‘[:alnum:]’ ‘\n’
Collapse horizontal whitespacetr -s ‘[:blank:]’ ‘ ‘

Convert lowercase text to uppercase

I prefer pairing the lower and upper character classes because that states the conversion directly and leaves other characters alone.

echo 'linuxforDevices' | tr '[:lower:]' '[:upper:]'

The output is LINUXFORDEVICES.

Tr Command in Linux Basic
Lowercase letters become uppercase while the rest of the line stays in place.

Delete characters or keep a class

Use -d to remove characters in the set. Add -c to select its complement, then -d removes everything outside the set.

printf '%s\n' 'Batch A-1042' | tr -cd '[:digit:]\n'
printf '%s\n' 'Batch A-1042' | tr -d '[:digit:]'

The first command prints 1042 on its own line because the selected set includes the newline escape. Without it, -cd removes the line ending along with every non-digit.

tr keeps the digit 1042 from the input string
The command retains the digits and the newline while deleting other characters.

Translate the complement of a set

The -c option translates characters outside SET1. The terminal capture shows echo adding a newline outside the set containing only s, so that line break becomes z and the next prompt appears beside the output.

echo 'mississippi' | tr -c 's' 'z'
printf '%s\n' 'mississippi' | tr -c 's\n' 'z'

I saw the first form turn the line ending into another z. I kept the newline in the excluded set in the second, so the line ending remains.

GNU tr extends the one-character replacement across the complement set.

Tr Command Complement Characters
The final z is the newline translated by the complement operation, so the shell prompt follows it on the same line.

Split text at separators

Translate runs of non-alphanumeric characters to a newline and squeeze repeated separators to put each word on its own line. The -c selects characters outside the alphanumeric class, while -s prevents a run of spaces from creating blank lines.

echo 'Linux For Devices' | tr -cs '[:alnum:]' '\n'

The output contains one word per line. This is a token split, not a general word parser, because punctuation and locale rules determine which characters stay in the alphanumeric set.

Tr Command Cases
Runs of separators become line breaks between the words.

Change tabs and squeeze repeated whitespace

Use [:blank:] to translate horizontal whitespace without touching line breaks. The terminal capture shows [:space:] translating the added newline to a tab, which puts the next prompt on the same line.

printf '%s\n' 'Linux is the Geekiest OS!' | tr '[:blank:]' '\t'
printf 'red   blue\n' | tr -s '[:blank:]' ' '

The first command marks word boundaries with tabs and preserves the ending line break.

Linux Tr Command Space By Tabs
This capture shows [:space:] translating the line break to a tab as well as changing the visible separators.

Squeezing checks repeated characters in the last specified array. It reduces each run to one character rather than trimming leading or trailing whitespace.

Tr Space Squeeze
Squeezing reduces each run to one whitespace character. It does not trim the remaining leading space.

To count lines after a transformation, use wc to count lines in a file. To inspect the source, cat and more display file contents, and the Linux man command opens local documentation.

Why tr changes line breaks

Character classes apply to every matching character in the input, including line breaks when a class or its complement includes them. That is why [:space:] can change a newline while [:blank:] leaves it alone.

A translation set maps characters by position. GNU tr repeats the last character of a shorter SET2 to fill the translation array, while -t truncates SET1 to SET2’s length.

printf 'abc\n' | tr 'abc' 'XY'
printf 'abc\n' | tr -t 'abc' 'XY'

The outputs are XYY and XYc. Quote bracket expressions to protect them from shell filename expansion. Redirect to a different output file because the shell truncates its destination before tr reads.

GNU tr works on bytes, so a character outside the current locale’s single-byte range may not behave like one Unicode character, as the Linux tr(1) manual notes. Use a string-aware tool for Unicode-aware or multi-character replacements.

Vim search-and-replace handles string-level changes, and terminal text editors let you review a file interactively.

Keep tr for character-level changes

When a task is one-character mapping, deletion, or squeezing, tr keeps the transformation readable in a pipeline. I use the character set to define exactly what changes, and I include the newline only when I intend to transform it.

  • Use tr when each input character has a character-level action.
  • Choose another command when the match spans a word or phrase.
printf 'one two\n' | tr ' ' '\n'

For substitutions that match whole words or phrases, move to a string-aware command instead. A single-character tool stays predictable when the boundary is one character at a time.

Linux tr command questions

The command’s character-level model answers these questions about its options and limits.

What does the tr command do in Linux?

It translates, deletes, or squeezes selected characters from standard input and writes the result to standard output.

How do I keep tr from changing newlines?

Use [:blank:] for horizontal whitespace. If you use -c, include newline in SET1 when line endings need to pass through unchanged.

Does tr edit a file in place?

No. It reads standard input and writes standard output. Redirect to a different destination file if you want to save the result.

How many character sets does tr take?

Use one set for deletion or squeezing, and two sets for translation. Put any option flags before the sets.

How do I stop tr when it waits for input?

Press Ctrl-D on an empty terminal line to signal end-of-file. In a pipeline, tr exits when its input reaches end-of-file, and Ctrl-C interrupts it.