Escape special characters from variables

I have

#!/usr/bin/bash
search="ldo_vrf18 {"
replace="$search"'                      compatible = "regulator-fixed";
                        regulator-name = "vrf18";
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <1800000>;
                        regulator-enable-ramp-delay = <120>;'
sed -i "s/$search/$replace/g" output.file

The result is

sed: -e expression #1, char 62: unterminated `s' command

I suspect some values arent being escape in replace. Is there a way to escape them?
I have tried sed -i 's/'"$search"'/'"$replace"'/g' output.file with the same result

Asked By: Bret Joseph

||

The problem is with the newlines in the $replace variable, which are interpreted by sed as end of command.

In order to solve that in GNU sed, you’ll need to replace the new lines in your $replace variable with a literal n:

replace=${replace//$'n'/\n}

Note: The solution above will not work in all sed implementations, as it’s an extended feature in some versions (for instance, in GNU sed). According to the POSIX standards:

Each embedded <newline> in the text shall be preceded by a
backslash. Other backslashes in text shall be removed+, and the
following character shall be treated literally.

So on POSIX sed, the literal n will lose it’s meaning as a newline and be treated just as a literal n character. For a portable solution that would work on all sed implementations, precede the actual newlines with a backslash:

replace=${replace//$'n'/\$'n'}

+ Except for backslash followed by a digit:

The characters "n", where n is a digit, shall be replaced by the
text matched by the corresponding backreference expression. […] For
each other backslash ( ‘‘ ) encountered, the following character
shall lose its special meaning
(if any).

Answered By: aviro