2013-07-03 31 views
3

混合引用变量扩展我有这个sed的oneliner巴什 - 与SED产量坏替代

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

很显然,我需要keyvaldeval在sed扩大变量的问题。所以我需要围绕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

您是否尝试过单外引号? 'sed'...'' – svante

+0

当然...变量不会扩展,然后... – bartimar

回答

4

event not found仅在交互式shell的一个问题。如果你先运行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"]]>

+0

不错,谢谢你的解释! :) – bartimar

2

您可以使用单独的单引号字符串:因为histexpand默认启用

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

尝试一个小例子'sed's /'$ key'//'''sed:-e expression# 1,char 3:未终止的'命令' – bartimar

+0

您确定先导出'key'变量吗?例如:'export key =“o”;回声“你好”| sed's /'$ key'//'' – svante

+0

我为什么要导出它?我只需要在脚本中需要它。 – bartimar