Home > Back-end >  Replace one character by the other (and vice-versa) in shell
Replace one character by the other (and vice-versa) in shell

Time:11-04

Say I have strings that look like this:

$ a='/o\\'
$ echo $a
/o\
$ b='\//\\\\/'
$ echo $b
\//\\/

I'd like a shell script (ideally a one-liner) to replace / occurrences by \ and vice-versa.

Suppose the command is called invert, it would yield (in a shell prompt):

$ invert $a
\o/
$ invert $b
/\\//\

For example using sed, it seems unavoidable to use a temporary character, which is not great, like so:

$ echo $a | sed 's#/#%#g' | sed 's#\\#/#g' | sed 's#%#\\#g'
\o/
$ echo $b | sed 's#/#%#g' | sed 's#\\#/#g' | sed 's#%#\\#g'
/\\//\

For some context, this is useful for proper printing of git log --graph --all | tac (I like to see newer commits at the bottom).

CodePudding user response:

tr is your friend:

% echo 'abc' | tr ab ba      
bac
% echo '/o\' | tr '\\/' '/\\'
\o/

(escaping the backslashes in the output might require a separate step)

CodePudding user response:

If you want to replace every instance of / with \, you can uses the y command of sed, which is quite similar to what tr does:

$ a='/o\'
$ echo "$a"
/o\
$ echo "$a" | sed 'y|/\\|\\/|'
\o/
$ b='\//\\/'
$ echo "$b"
\//\\/
$ echo "$b" | sed 'y|/\\|\\/|'
/\\//\

CodePudding user response:

I think this can be done with (g)awk:

$ echo a/\\b\\/c | gawk -F "/" 'BEGIN{ OFS="\\" } { for(i=1;i<=NF;i  ) gsub(/\\/,"/",$i); print $0; }'
a\/b/\c
$ echo a\\/b/\\c | gawk -F "/" 'BEGIN{ OFS="\\" } { for(i=1;i<=NF;i  ) gsub(/\\/,"/",$i); print $0; }'
a/\b\/c
$
  • -F "/" This defines the separator, The input will be split in "/", and should no longer contain a "/" character.
  • for(i=1;i<=NF;i ) gsub(/\\/,"/",$i);. This will replace, in all items in the input, the backslash (\) for a slash (/).
  • Related