我有一个标签
<html>
<body>
<div class='a grab'>
</div>
<button class='b grab'>
</button>
</body>
</html>
<string name="currencysym">$</string>
中的以及动态更改string.xml
符号的内容。使用以下命令但不起作用:
$
获取输出:
currencysym=₹
sed -i '' 's|<string name="currencysym">\(.*\)<\/string>|<string name="currencysym">'"<!\[CDATA\[${currencysym}\]\]>"'<\/string>|g'
“&amp;”已删除...
但我需要:
<string name="currencysym"><![CDATA[<string name="currencysym">$</string>#x20B9;]]></string>
答案 0 :(得分:3)
<..>\(.*\)<..>
更好地使用<..>\([^<]*\)<..>
&
具有特殊含义,它表示模式的整个匹配(\0
)。这就是为什么你看到<...>..</..>
来到你的输出。如果你想要它是文字的,你应该逃避它 - &gt; \&
答案 1 :(得分:2)
第一个问题是行
currencysym=₹
这实际上显示为“将空分配给currencysym
并在后台启动没有进程”:
VAR=value command
来设置一个环境变量(或变量)或一个过程。这就是解释currencysym=
的方式。&
符号表示在后台启动进程,但没有指定命令,因此没有任何反应。#
之后的所有内容都被解释为注释,因此{B}的观点#x20B9;
只是空格。;
是一个命令分隔符,如&
,表示“在前台运行”。这里没有使用它,因为它是#
注释掉的。您必须要转义&
,#
和;
,或者只需将字符串放入单引号:currencysym=\&\#x20B9\;
或currencysym='₹'
。
现在最重要的是,&
在sed
中具有特殊含义,因此您需要在sed
命令中使用它之前将其转义。您可以直接在currencysym=\\\&\#x20B9\;
或currencysym='\₹'
等定义中执行此操作,也可以在使用内置bash功能调用sed
时执行此操作。而不是访问${currencysym}
,请参考${currencysym/&/\&}
。
您应该在sed
命令中使用双引号来确保扩展环境变量,但是不应该在不转义感叹号的情况下对引号进行双引号。
最后,您不需要捕获原始货币符号,因为您要替换它。您应该使您的模式更具体,因为*
量词是贪婪的,并且如果有多个,将转到该行的最后一个结束标记:
sed 's|<string name="currencysym">[^<]*</string>|<string name="currencysym"><![CDATA['"${currencysym/&/\&}"']]></string>|' test.xml
产量
<string name="currencysym"><![CDATA[₹]]></string>
修改强>
正如@fedorqui指出的那样,您可以使用此示例来展示捕获组的正确使用。您可以捕获要完全重复的部分(标记),并按原样将它们放回输出中:
sed 's|\(<string name="currencysym">\)[^<]*\(</string>\)|\1<![CDATA['"${currencysym/&/\&}"']]>\2|' test.xml
答案 2 :(得分:1)
sed -i '' 's|\(<string name="currencysym">\)[^<]*<|\1<![CDATA[\₹]]><|g' YourFile
&
.*
进行分组与您需要的所有非首先<
不同。特别是使用g
选项意味着可能会发生几次出现,在这种情况下,第一个字符串名称和最后一个 之间的连接是中间部分(您的组)。&
(未转义)的carrefull,表示替换部分中的“整个搜索模式查找”