Issue
I would like this script
sed -i "/INTERPRETER_PYTHON_DISTRO_MAP/,/version_added/ {
/default/a\ linux:\n '8': \/usr\/local
}" base.yaml
rewritten to fit one line. Here's what I tried:
sed -i "/INTERPRETER_PYTHON_DISTRO_MAP/,/version_added/ {/default/a\ linux:\n '8': \/usr\/local}" base.yaml
but it isn't working. I'm currently being harassed by this error:
sed: -e expression #1, char 0: unmatched `{'
Solution
An ANSI C string -- with $''
-- can contain backslash escapes, like \n
-- so you can have a newline in sed
's arguments while still having the shell command invoking sed
be only one line.
sed -i $'/INTERPRETER_PYTHON_DISTRO_MAP/,/version_added/ {\n /default/a\\ linux:\\n \'8\': \\/usr\\/local\n }'
Insofar as your real goal is to build a RUN command for a Dockerfile, you can use jq
to tell you how to escape any arbitrary command -- including multi-line commands -- as JSON:
printf '%s\0' sed -i "/INTERPRETER_PYTHON_DISTRO_MAP/,/version_added/ {
/default/a\ linux:\n '8': \/usr\/local
}" base.yml | jq -Rrs '"RUN \(. | split("\u0000") | tojson)"'
...emits as output:
RUN ["sed","-i","/INTERPRETER_PYTHON_DISTRO_MAP/,/version_added/ {\n /default/a\\ linux:\\n '8': \\/usr\\/local\n }","base.yml"]
Answered By - Charles Duffy Answer Checked By - David Goodson (WPSolving Volunteer)