What if, in sed, you have lots of slashes in the pattern and/or replacement?
One solution is to escape them all (the so-called toothsaw effect):
sed 's/\/a\/b\/c\//\/d\/e\/f\//' # change "a/b/c/" to "d/e/f/"
but that is ugly and unreadable. It's a not-so-known fact that sed can use any character as separator for the "s" command. Basically, sed takes whatever follows the "s" as the separator. So, our code above can be rewritten for example in one of the following ways:
sed 's_/a/b/c/_/d/e/f/_' sed 's;/a/b/c/;/d/e/f/;' sed 's#/a/b/c/#/d/e/f/#' sed 's|/a/b/c/|/d/e/f/|' sed 's /a/b/c/ /d/e/f/ ' # yes, even space # etc.
An even less-known fact is that you can use a different delimiter even for patterns used in addresses, using a special syntax:
# do this (ugly)... sed '/\/a\/b\/c\//{do something;}' # ...or these (better) sed '\#/a/b/c/#{do something;}' sed '\_/a/b/c/_{do something;}' sed '\%/a/b/c/%{do something;}' # etc.
I’ve often used this feature of sed for search/replace lists with my colleagues... I just tell them to create me a spreadsheet with “find” string in first cell and replace in second... then export to text... a little recursive sed script using either spaces or commas as delimiter/separator is magic to them.....
Note that this does not work when the sed expression begins with the delimiter, such as the 'delete' case or 'change only lines that have this text' case:
$ cat test
this
that
this
orthat
orthis
$
$ sed '/this/d' test
that
orthat
$
$ sed '_this_d' test
sed: -e expression #1, char 1: unknown command: `_'
$
$ sed '/this/s/^/added/g' test
addedthis
that
addedthis
orthat
addedorthis
$
$ sed '?this?s?^?added?g' test
sed: -e expression #1, char 1: unknown command: `?'
$
It just has to be escaped, as explained in the article and in the sed docs.
Not any character will do, only single byte ones:
sed -i 'sñasdñfghñg' tt
sed: -e expression #1, char 2: delimiter character is not a single-byte character
Not quite "any character" - a backslash won't work
At least with GNU sed, a backslash works perfectly fine:
You may be running into shell quoting or escaping problems instead.
Did a test on Solaris and on Sun sed the backslash doesn't work. However with GNU sed it works. So for compability one shouldn't use backslash.
great tip, why to escape anymore! :)
Thanks, nice post. You learn something everyday :-)