Universal sed command for finding and replacing values

sedstring

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?

Best Answer

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
Related Question