3

我对这个 sed oneliner 有问题

sed -i -n "1h; 1!H; ${g; :a s/\(Name=\"$key\".*<\!\[CDATA\[\"\)$val\(\"\]\]>\)/\1$deval\2/;ta p}"

显然我需要扩展变量keyvaldeval在 sed 中。所以我需要"around 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: "\"

这里发生了什么?我怎样才能使这项工作?

4

2 回答 2

4

event not found仅在交互式 shell 中是一个问题,因为histexpand默认情况下已启用。如果您set +H先运行或将其放入脚本并从那里运行,Bash 将不理会您!的 s。

${..}是变量替换语法(因此损坏的值给出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"]]>

于 2013-07-03T15:46:53.607 回答
2

您可以使用单独的单引号字符串:

sed -i -n '1h; 1!H; ${g; :a s/\(Name='"$key"'.*<\!\[CDATA\[\"\)'"$val"'\(\"\]\]>\)/\1'"$deval"'\2/;ta p}'
于 2013-07-03T09:58:40.420 回答