Skip to content
 

Using different delimiters in sed

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.

9 Comments

  1. Me says:

    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.....

  2. John says:

    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: `?'
    $

  3. Berserk9779 says:

    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

  4. Tom Warfield says:

    Not quite "any character" - a backslash won't work

    • waldner says:

      At least with GNU sed, a backslash works perfectly fine:

      $ echo abc | sed 's\b\B\'
      aBc

      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.

        root@solaris11:~# echo abc | sed 's\b\B\'
        abc
        root@solaris11:~# echo abc | gsed 's\b\B\'
        aBc
        
  5. Hubson says:

    great tip, why to escape anymore! :)

  6. Sonia says:

    Thanks, nice post. You learn something everyday :-)