4

Is there a way to use sed to substitute any string for any other string? Because sed uses a delimiter character for the find and replace expression, I can't figure out a way to write a sed command capable of substituting a string with potentially any character (or all characters) in any path for any other string (which may also contain any character).

Here is an example of what I have that does not work:

new_value="foobar"
old_value="baz"
echo "$some_path" | sed -e "s|$old_value|$new_value|"

This works unless $new_value or $old_value contains a pipe, in which case the command is invalid because the substitution syntax is broken by the variables used in the sed expression.

Is there a way to use sed to substitute any string for any other string?

If not, is there a Unix good alternative?

Stratus3D
  • 141

2 Answers2

4

A simple way around this is to escape everything in your variables before calling sed:

new_value="foo|bar"
old_value="ba|z"
new_value=$(printf '%q' "$new_value")
old_value=$(printf '%q' "$old_value")
some_path="/path/to/ba|z/file"

And then:

$ echo "$some_path" | sed -e "s|$old_value|$new_value|"
/path/to/foo|bar/file

The trick here is the printf '%q'. From help printf (showing the help of bash's builtin printf):

  %q    quote the argument in a way that can be reused as shell input
terdon
  • 242,166
1

you can use shell paramater substitution to escape the needed char:

sed -e "s|${old_value//|/\\|}|${new_value//|/\\|}|"
glenn jackman
  • 85,964