tr: замена одного символа двумя символами

может ли tr заменить один символ двумя символами?

Я пытаюсь заменить " ~ " на "~n", но вывод не создает новую строку.

$ echo "asdlksad ~ adlkajsd ~ 12345" | tr "~" "~n"
asdlksad ~ adlkajsd ~ 12345

5 ответов


нет, tr специально предназначен для замены отдельных символов одиночными символами (или, в зависимости от параметров командной строки, для удаления символов или замены запусков одного символа одним вхождением.).

sed - пожалуй, лучший инструмент для этой работы:

$ echo "asdlksad ~ adlkajsd ~ 12345" | sed 's/~/~\n/g'
asdlksad ~
 adlkajsd ~
 12345

(обратите внимание, что для этого требуется sed для интерпретации люфта-n \n последовательности, как символ новой строки. GNU sed делает это, но POSIX не указывает его, кроме в рамках регулярного выражения, и есть определенно более старые версии sed это не так.)


вы можете пойти с awk, пусть переменная FS/OFS сделает работу за вас:

awk -F'~' -v OFS="~\n" '=' 

тест с вашим примером:

kent$ awk -F'~' -v OFS="~\n" '=' <<< "asdlksad ~ adlkajsd ~ 12345" 
asdlksad ~
 adlkajsd ~
 12345

не могу, к сожалению.

tr предназначен для транслитерации одного персонажа с другим.

есть множество вариантов, но я бы использовал awk, то есть

echo "asdlksad ~ adlkajsd ~ 12345" | awk '{gsub(/[~]/, "&\n")};1'

выход

asdlksad ~
 adlkajsd ~
 12345

tr может выполнять только 1-1 перевод.

вот один из способов сделать это использование pure Bash:

s='"asdlksad ~ adlkajsd ~ 12345'
r=$'~\n'
echo -e "${s//\~/$r}"
asdlksad ~
 adlkajsd ~
 12345

echo "asdlksad ~ adlkajsd ~ 12345" | sed 's/~/~|/g' | tr '|' '\n'

--Это будет работать идеально, так как sed имеет проблему замены \n