haelix
haelix

Reputation: 4555

Escape file name for use in sed substitution

How can I fix this:

abc="a/b/c"; echo porc | sed -r "s/^/$abc/"
sed: -e expression #1, char 7: unknown option to `s'

The substitution of variable $abc is done correctly, but the problem is that $abc contains slashes, which confuse sed. Can I somehow escape these slashes?

Upvotes: 4

Views: 2645

Answers (5)

a1an
a1an

Reputation: 3636

As for the escaping part of the question I had the same issue and resolved with a double sed that can possibly be optimized.

escaped_abc=$(echo $abc | sed "s/\//\\\AAA\//g" | sed "s/AAA//g")

The triple A is used because otherwise the forward slash following its escaping backslash is never placed in the output, no matter how many backslashes you put in front of it.

Upvotes: 0

Rok Strniša
Rok Strniša

Reputation: 7202

The GNU manual for sed states that "The / characters may be uniformly replaced by any other single character within any given s command."

Therefore, just use another character instead of /, for example ::

abc="a/b/c"; echo porc | sed -r "s:^:$abc:"
  1. Do not use a character that can be found in your input. We can use : above, since we know that the input (a/b/c/) doesn't contain :.

  2. Be careful of character-escaping.

    • If using "", Bash will interpret some characters specially, e.g. ` (used for inline execution), ! (used for accessing Bash history), $ (used for accessing variables).

    • If using '', Bash will take all characters literally, even $.

    • The two approaches can be combined, depending on whether you need escaping or not, e.g.:

      abc="a/b/c"; echo porc | sed 's!^!'"$abc"'!'
      

Upvotes: 6

przemoc
przemoc

Reputation: 3869

You don't have to use / as pattern and replace separator, as others already told you. I'd go with : as it is rather rarely used in paths (it's a separator in PATH environment variable). Stick to one and use shell built-in string replace features to make it bullet-proof, e.g. ${abc//:/\\:} (which means replace all : occurrences with \: in ${abc}) in case of : being the separator.

$ abc="a/b/c"; echo porc | sed -r "s:^:${abc//:/\\:}:"
a/b/cporc

Upvotes: 3

sarnold
sarnold

Reputation: 104080

Note that sed(1) allows you to use different characters for your s/// delimiters:

$ abc="a/b/c"
$ echo porc | sed -r "s|^|$abc|"
a/b/cporc
$ 

Of course, if you go this route, you need to make sure that the delimiters you choose aren't used elsewhere in your input.

Upvotes: 7

mugetsu
mugetsu

Reputation: 4398

backslash:

abc='a\/b\/c'

space filling....

Upvotes: 1

Related Questions