Reputation: 3534
I have problem with this sed oneliner
sed -i -n "1h; 1!H; ${g; :a s/\(Name=\"$key\".*<\!\[CDATA\[\"\)$val\(\"\]\]>\)/\1$deval\2/;ta p}"
Obviously I need to expand variable key
, val
and deval
in sed. So I need the "
around sed command.
With this command I get
bash: !H: event not found
escaping the !
corrects it
sed -i -n "1h; 1\!H; ${g; :a s/\(Name=\"$key\".*<\!\[CDATA\[\"\)$val(\"\]\]>\)/\1$deval\2/;ta p}"
With this I get
bash: sed -i -n "1h; 1\!H; ${g; :a s/\(Name=\"$key\".*<\!\[CDATA\[\"\)$val\(\"\]\]>\)/\1$deval\2/;ta p}" :bad substitution
So I guess the {
is a problem. Trying to fix it like this
sed -i -n "1h; 1\!H; $\{g; :a s/\(Name=\"$key\".*<\!\[CDATA\[\"\)$val(\"\]\]>\)/\1$deval\2/;ta p}"
yields
sed: -e expression 1, char 6: unknown command: "\"
What is going on here? How can I make this work?
Upvotes: 3
Views: 1767
Reputation: 22969
You can use separate single-quoted strings:
sed -i -n '1h; 1!H; ${g; :a s/\(Name='"$key"'.*<\!\[CDATA\[\"\)'"$val"'\(\"\]\]>\)/\1'"$deval"'\2/;ta p}'
Upvotes: 2
Reputation: 123470
event not found
is only a problem in interactive shells because histexpand
is enabled by default. If you either run set +H
first or put it in a script and run it from there, Bash will leave your !
s alone.
${..}
is variable substitution syntax (so a mangled value gives bad substitution
). Let sed
treat it as a block of commands to do on the final line by escaping the $
, as in \${ .. }
.
In full:
set +H
key="foo"
val="bar"
deval="puppies"
echo 'Name="foo" <![CDATA["bar"]]>' > file
sed -i -n "1h; 1!H; \${g; :a s/\(Name=\"$key\".*<!\[CDATA\[\"\)$val\(\"\]\]>\)/\1$deval\2/;ta p}" file
cat file
Will print Name="foo" <![CDATA["puppies"]]>
Upvotes: 4