Why doesn’t the command tr “\’\\\”\?\!“ ”01234″ work

special characterstr

In terminal, if I define some variable char as follows:

export char=\'\\\"\?\!

In effect, char is the string

'\"?!

And then I use the tr command to replace '\"?! with numbers 01234

tr "\'\\\"\?\!" "01234"

And I thought I would get

01234

Instead, I got

0\123

I would be really grateful if someone could explain to me what happened.

It seems replacing each character individually with the sed command avoids this problem, but why?

Best Answer

Not just the shell, but tr itself also interprets backslash as a special escaping character, see its manual for details. So you need to make sure that tr receives literal \\ (two backslashes) when you want to replace backslashes. This might be done e.g. by char=...\\\\... in the shell, this part doesn't need further explanation since you understand correctly how the shell handles the backslash.

This might be inconvenient for you here, but is convenient in many other situations, and allows sets of characters, or the NUL byte to be part of the search or replace set (which wouldn't be possible otherwise). E.g. to convert NUL-delimited strings to newline-delimited you can do something like tr '\0' '\n' < /proc/1234/environ, or to lowercase a string use tr '[:upper:]' '[:lower:]'. These wouldn't be possible if tr didn't have an escape character.

Related Question