Не только оболочка, но и сам tr
также интерпретирует обратную косую черту как специальный экранирующий символ, подробности см. в руководстве. Таким образом, вам нужно убедиться, что tr
получает буквально\\
(две обратные косые черты ), когда вы хотите заменить обратную косую черту. Это может быть сделано, например. по char=...\\\\...
в оболочке, эта часть не нуждается в дальнейшем объяснении, так как вы правильно понимаете, как оболочка обрабатывает обратную косую черту.
Это может быть неудобно для вас здесь, но удобно во многих других ситуациях и позволяет наборам символов или байту NUL быть частью набора поиска или замены (, что было бы невозможно в противном случае ). Например. чтобы преобразовать строки с разделителями NUL -в разделители новой строки -, вы можете сделать что-то вроде tr '\0' '\n' < /proc/1234/environ
или использовать строку в нижнем регистре tr '[:upper:]' '[:lower:]'
. Это было бы невозможно, если бы tr
не имел escape-символа.
Всегда заключайте строки и скрипты в одинарные кавычки ('
), если вам не нужно использовать двойные кавычки ("
), чтобы интерпретировать их оболочкой. См. https://mywiki.wooledge.org/Quotes. Используя двойные кавычки, вы приглашаете оболочку и, таким образом, попадаете в «убегающий» ад, где вам нужно сначала экранировать символы в строке, чтобы оболочка использовала их, а затем снова экранировать их для использования инструментом, поэтому вам нужно добавить несколько слои escape вместо 1. Только не делайте этого, используйте вместо этого одинарные кавычки:
$ printf '%s\n' ''\''\"?!'
'\"?!
$ printf '%s\n' ''\''\"?!' | tr ''\''\\"?!' '01234'
01234
То же самое верно, когда вы определяете свою переменную char
. Вместо всех этих обратных слэшей:
export char=\'\\\"\?\!
просто одинарное -корректное цитирование строки:
$ export char=''\''\"?!'
$ printf '%s\n' "$char"
'\"?!
$ printf '%s\n' "$char" | tr ''\''\\"?!' '01234'
01234
В вышеизложенном все, что вам нужно знать, это то, что для получения '
внутри заключенной строки'
-в оболочке '\''
и вам нужно экранировать обратную косую черту в tr
, чтобы tr
знал рассматривать его как буквальную обратную косую черту, а не экранирование для последующего "
.