How to replace one character with two characters using tr
Asked Answered
P

5

56

Can tr replace one character with two characters?

I am trying to replace "~" with "~\n" but the output does not produce the newline.

$ echo "asdlksad ~ adlkajsd ~ 12345" | tr "~" "~\n"
asdlksad ~ adlkajsd ~ 12345
Pola answered 21/8, 2013 at 18:55 Comment(0)
E
48

No, tr is specifically intended to replace single characters by single characters (or, depending on command-line options, to delete characters or replace runs of a single character by one occurrence.).

sed is probably the best tool for this particular job:

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

(Note that this requires sed to interpret the backlash-n \n sequence as a newline character. GNU sed does this, but POSIX doesn't specify it except within a regular expression, and there are definitely older versions of sed that don't.)

Exoenzyme answered 21/8, 2013 at 19:45 Comment(0)
W
8

tr can only do 1 to 1 translation.

Here is one way of doing that using pure Bash:

s='"asdlksad ~ adlkajsd ~ 12345'
r=$'~\n'
echo -e "${s//\~/$r}"
asdlksad ~
 adlkajsd ~
 12345
Weaken answered 21/8, 2013 at 20:4 Comment(2)
This is probably more efficient than calling utilities like awk or sed.Horsley
See nice explanation of the syntax here: https://mcmap.net/q/45307/-replace-one-substring-for-another-string-in-shell-scriptRosena
D
7

you could go with awk, let FS/OFS variable do the job for you:

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

test with your example:

kent$ awk -F'~' -v OFS="~\n" '$1=$1' <<< "asdlksad ~ adlkajsd ~ 12345" 
asdlksad ~
 adlkajsd ~
 12345
Dunford answered 21/8, 2013 at 20:3 Comment(1)
This solved a problem for me, but it was not clear to me what was happening, so I dug a little deeper for some clarity: "-F" == "input field separator" and "-OFS" == "output field separator" (the trick here being that the "OFS" can be multi-character) and the "<<<" passes the quoted string to awk as STDIN (in the same shell) - this avoids the issue with pipes where the transaction is done in a different sub-shell.Hoodwink
M
2

no can do, sorry.

tr is meant to transliterate one character with another.

there are numerous options, but I would use awk, i.e.

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

output

asdlksad ~
 adlkajsd ~
 12345
Mullens answered 21/8, 2013 at 19:35 Comment(1)
Instead of /[~]/, the shorter form /~/ also works. The ;1 at the end is not necessary. (Or is it, for some obscure old operating system?)Batton
A
0
echo "asdlksad ~ adlkajsd ~ 12345" | sed 's/~/~|/g' | tr '|' '\n'

--This will work perfect, since sed having a problem replacing \n

Austriahungary answered 19/6, 2015 at 12:12 Comment(1)
It doesn't work if the input contains | elsewhere.Batton

© 2022 - 2024 — McMap. All rights reserved.