Bash脚本“&”符号创建问题

Bash脚本“&”符号创建问题,bash,sed,Bash,Sed,我有一个标签 <string name="currencysym">$</string> 获取输出: <string name="currencysym"><![CDATA[<string name="currencysym">$</string>#x20B9;]]></string> &已删除 但我需要: <string name="currencysym"><![CDATA[&

我有一个标签

<string name="currencysym">$</string> 
获取输出:

<string name="currencysym"><![CDATA[<string name="currencysym">$</string>#x20B9;]]></string>
&已删除

但我需要:

<string name="currencysym"><![CDATA[&#x20B9;]]></string>
使用xml解析器/工具处理xml是首选 而不是\.\更好地使用\[^ 使用xml解析器/工具处理xml是首选 而不是\.\更好地使用\[^ 您保留在缓冲区中的组在代码中是错误的,我保留第一部分而不是第一部分& 分组a.*与所有untl first不同 您保留在缓冲区中的组在代码中是错误的,我保留第一部分而不是第一部分&
分组a.*与所有分组不同,直到第一个问题是行

currencysym=&#x20B9;
这实际上是将空赋值给currencysym,并在后台不启动任何进程:

在bash中,您可以通过执行VAR=value命令来设置一个或多个环境变量,也可以设置一个或多个过程的一次运行。 &符号表示在后台启动进程,但没有指定命令,因此不会发生任何事情。 之后的所有内容都被解释为注释,因此从Bash的角度来看,x20B9;只是空白。 另外,;是一个命令分隔符,如&,意思是在前台运行。这里不使用它,因为它被注释掉了。 您必须转义&、and;,或者将字符串放在单引号中:currencysym=\&\x20B9\;或currencysym='&x20B9;'

现在,除此之外,&在sed中有一个特殊的含义,因此在sed命令中使用它之前,您需要对它进行转义。您可以直接在定义中执行此操作,如currencysym=\\\&\x20B9\;或currencysym='\&x20B9',或者您可以使用内置bash功能在对sed的调用中执行此操作。不访问${currencysym${currencysym/&/\&}

在sed命令中,应在变量周围使用双引号,以确保环境变量已展开,但不应在不转义它们的情况下使用双引号

最后,您不需要捕获原始货币符号,因为您要替换它。但是,您应该使您的模式更加具体,因为*量词是贪婪的,如果有多个,它将转到行上的最后一个结束标记:

sed 's|<string name="currencysym">[^<]*</string>|<string name="currencysym"><![CDATA['"${currencysym/&/\&}"']]></string>|' test.xml
屈服

<string name="currencysym"><![CDATA[&#x20B9;]]></string>
编辑

正如@fedorqui所指出的,您可以使用此示例来展示捕获组的正确使用。您可以捕获要完全重复标记的部分,并按原样将其放回输出中:

sed 's|\(<string name="currencysym">\)[^<]*\(</string>\)|\1<![CDATA['"${currencysym/&/\&}"']]>\2|' test.xml

第一个问题是线路

currencysym=&#x20B9;
这实际上是将空赋值给currencysym,并在后台不启动任何进程:

在bash中,您可以通过执行VAR=value命令来设置一个或多个环境变量,也可以设置一个或多个过程的一次运行。 &符号表示在后台启动进程,但没有指定命令,因此不会发生任何事情。 之后的所有内容都被解释为注释,因此从Bash的角度来看,x20B9;只是空白。 另外,;是一个命令分隔符,如&,意思是在前台运行。这里不使用它,因为它被注释掉了。 您必须转义&、and;,或者将字符串放在单引号中:currencysym=\&\x20B9\;或currencysym='&x20B9;'

现在,除此之外,&在sed中有一个特殊的含义,因此在sed命令中使用它之前,您需要对它进行转义。您可以直接在定义中执行此操作,如currencysym=\\\&\x20B9\;或currencysym='\&x20B9',或者您可以使用内置bash功能在对sed的调用中执行此操作。不访问${currencysym${currencysym/&/\&}

在sed命令中,应在变量周围使用双引号,以确保环境变量已展开,但不应在不转义它们的情况下使用双引号

最后,您不需要捕获原始货币符号,因为您要替换它。但是,您应该使您的模式更加具体,因为*量词是贪婪的,如果有多个,它将转到行上的最后一个结束标记:

sed 's|<string name="currencysym">[^<]*</string>|<string name="currencysym"><![CDATA['"${currencysym/&/\&}"']]></string>|' test.xml
屈服

<string name="currencysym"><![CDATA[&#x20B9;]]></string>
编辑

正如@fedorqui所指出的,您可以使用此示例来展示捕获组的正确使用。您可以捕获要完全重复标记的部分,并按原样将其放回输出中:

sed 's|\(<string name="currencysym">\)[^<]*\(</string>\)|\1<![CDATA['"${currencysym/&/\&}"']]>\2|' test.xml

请提供您的输入和预期输出。请提供您的输入和预期输出。您的1.根据该工具是否适用于OP1提供了最佳建议。根据该工具是否适用于OPFor Mac:sed-i’s提供了最佳建议|[^ |'strings.xmlGood one!您可以捕获它并打印回去。@Rawan-25。我不确定我在Mac上看到了什么不同。@Rawan-25。很高兴听到这个消息。查看更多信息顺便说一句。一般来说,XML+regex不是一个好主意,尽管对于像您这样的简单情况,它是最快和最简单的事情。对于Mac:sed-I's|[^ |'strings.xmlGood one!您可以捕获它并打印回去,而不是打印回去。@Rawan-25。我不确定我是否在Mac上看到了差异。@Rawan-25。很高兴听到它。Che 顺便说一句,查看更多信息。一般来说,XML+regex不是一个好主意,尽管对于像您这样的简单情况,它是最快、最简单的方法。