我有这个sed oneliner的问题
sed -i -n "1h; 1!H; ${g; :a s/\(Name=\"$key\".*<\!\[CDATA\[\"\)$val\(\"\]\]>\)/\1$deval\2/;ta p}"
显然,我需要在sed中扩展变量key
,val
和deval
。所以我需要"
周围的sed命令。
使用此命令我得到
bash: !H: event not found
转义!
纠正它
sed -i -n "1h; 1\!H; ${g; :a s/\(Name=\"$key\".*<\!\[CDATA\[\"\)$val(\"\]\]>\)/\1$deval\2/;ta p}"
有了这个,我得到了
bash: sed -i -n "1h; 1\!H; ${g; :a s/\(Name=\"$key\".*<\!\[CDATA\[\"\)$val\(\"\]\]>\)/\1$deval\2/;ta p}" :bad substitution
所以我猜{
是个问题。试图像这样修复它
sed -i -n "1h; 1\!H; $\{g; :a s/\(Name=\"$key\".*<\!\[CDATA\[\"\)$val(\"\]\]>\)/\1$deval\2/;ta p}"
产量
sed: -e expression 1, char 6: unknown command: "\"
这里发生了什么?我怎样才能做到这一点?
答案 0 :(得分:4)
event not found
只是交互式shell中的一个问题,因为默认情况下会启用histexpand
。如果您先运行set +H
或将其放入脚本并从那里运行,Bash将单独留下!
个。
${..}
是变量替换语法(因此错位值会给出bad substitution
)。让sed
通过转义$
将其视为要在最后一行执行的命令块,如\${ .. }
中所示。
完整:
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
将打印Name="foo" <![CDATA["puppies"]]>
答案 1 :(得分:2)
您可以使用单独的单引号字符串:
sed -i -n '1h; 1!H; ${g; :a s/\(Name='"$key"'.*<\!\[CDATA\[\"\)'"$val"'\(\"\]\]>\)/\1'"$deval"'\2/;ta p}'