dingalapadum
dingalapadum

Reputation: 2175

Replace one character with another and vice versa in a string

I want to replace all slashes '/' with backslashes '\' and vice versa.

My naive solution is to do this with tr but then I need a placeholder character, which I don't think is very pretty:

tr '/' '¢' | tr '\\' '/' | tr '¢' '\\'

and this also only works as long as there never appears a '¢' in my input, which in my case most probably is enough - but hey, who knows? Of course it is easy to take this same idea and make it more robust by using sed and then replace '¢' with some arbitrarily random string - like '½|#&¬_$' or something.

But I wanted to know if there is some single bash command to achieve this, which would make this thing shorter, more readable and more robust. Maybe sed can do this out of the box?


While we are at it, what is the correct name for this operation? Like 'bidirectional replace'. If I knew that my google-searches would probably have been more fruitful. I also tried 'swap characters' but I only found regular replacing stuff.

Upvotes: 2

Views: 1096

Answers (2)

user31264
user31264

Reputation: 6737

tr \\\\/ /\\\\

Input:

//fgdf\\

Output:

\\fgdf//

Why 4 backslashes? Two backslashes make one backslash in shell, so tr receives \\/ and /\\. It has its own backslash sequences, so it interprets two backslashes as a backshash.

Upvotes: 1

codeforester
codeforester

Reputation: 43039

You don't need an intermediate character for this since tr traverses the string only once and hence a character will never get replaced more than once. The following tr command should do it:

tr '/\' '\\/' <<< '//\\ then \\// and / and finally a \ in the string'

yields

\\// then //\\ and \ and finally a / in the string

Or, more simply:

tr ab ba <<< "ab ba bb aa" # yields "ba ab aa bb"

You can also use sed:

sed 'y#/\\#\\/#' <<< '//\\ then \\// and / and finally a \ in the string'

yields

\\// then //\\ and \ and finally a / in the string

From man sed:

[2addr]y/string1/string2/

Replace all occurrences of characters in string1 in the pattern space with the corresponding characters from string2. Any character other than a backslash or newline can be used instead of a slash to delimit the strings. Within string1 and string2, a backslash followed by an ``n'' is replaced by a newline character. A pair of backslashes is replaced by a literal backslash. Finally, a backslash followed by any other character (except a newline) is that literal character.

Upvotes: 6

Related Questions