Escaping both forward slash and back slash with sed
You need to escape (with backslash \
) all substituted slashes /
and all backslashes \
separately, so:
$ echo "/tmp/test/folder1/test.txt" | sed 's/\//\\\//g'
\/tmp\/test\/folder1\/test.txt
but that's rather unreadable.
However, sed
allows to use almost any character as a separator instead of /
, this is especially useful when one wants to substitute slash /
itself, as in your case, so using for example semicolon ;
as separator the command would become simpler:
echo "/tmp/test/folder1/test.txt" | sed 's;/;\\/;g'
Other cases:
If one wants to stick with slash as a separator and use double quotes then all escaped backslashes have to be escaped one more time to preserve their literal values:
echo "/tmp/test/folder1/test.txt" | sed "s/\//\\\\\//g"
if one doesn't want quotes at all then yet another backslash is needed:
echo "/tmp/test/folder1/test.txt" | sed s/\\//\\\\\\//g
Or, if the value is in a (bash) shell variable:
var=/tmp/test/folder1/test.txt
$ echo "${var//\//\\\/}"
\/tmp\/test\/folder1\/test.txt
The first //
start parameter expansion, saying to replace all matches with the replacement. The next \/
is the escaped /
to match, and the \\\/
is an escaped \
followed by an escaped /
as the replacement.
The final solution will be this one:
$ sed 's:/:\\/:g' <<<"$str"
\/tmp\/test\/folder1\/test.txt
But to explain how to get there:
Yes, you were missing one backslash:
$ str='/tmp/test/folder1/test.txt'
$ sed "s/\//\\\\\//g" <<<"$str"
\/tmp\/test\/folder1\/test.txt
I hope that one space will make it clear:
$ sed "s/\//\\\\ \//g" <<<"$str"
\ /tmp\ /test\ /folder1\ /test.txt
But, if you were to change the sed delimiter to :
(for example):
$ sed "s:\/:\\\\\/:g" <<<"$str"
\/tmp\/test\/folder1\/test.txt
But that is not strictly correct as the (now not special) /
does not need scaping:
$ sed "s:/:\\\\/:g" <<<"$str"
\/tmp\/test\/folder1\/test.txt
And, if you were to use single quotes instead of double quotes the shell will not change double \\
to one, so less \
will be correct:
$ sed 's:/:\\/:g' <<<"$str"
\/tmp\/test\/folder1\/test.txt
Which is quite cleaner.