First problem is the line
currencysym=₹
This actually reads as "assign empty to currencysym
and start no process in the background":
- In bash you can set an environment variable (or variables) just or one run of a process by doing
VAR=value command
. This is how currencysym=
is being interpreted.
- The
&
symbol means start process in the background, except there is no command specified, so nothing happens.
- Everything after
#
is interpreted as a comment, so #x20B9;
is just whitespace from Bash's point of view.
- Also,
;
is a command separator, like &
, which means "run in foreground". It is not used here because it is commented out by #
.
You have to either escape &
, #
and ;
, or just put your string into single quotes: currencysym=\&\#x20B9\;
or currencysym='₹'
.
Now on top of that, &
has a special meaning in sed
, so you will need to escape it before using it in the sed
command. You can do this directly in the definition like currencysym=\\\&\#x20B9\;
or currencysym='\₹'
, or you can do it in your call to sed
using builtin bash functionality. Instead of accessing ${currencysym}
, reference ${currencysym/&/\&}
.
You should use double-quotes around variables in your sed
command to ensure that your environment variables are expanded, but you should not double-quote exclamation marks without escaping them.
Finally, you do not need to capture the original currency symbol since you are going to replace it. You should make your pattern more specific though since the *
quantifier is greedy and will go to the last closing tag on the line if there is more than one:
sed 's|<string name="currencysym">[^<]*</string>|<string name="currencysym"><![CDATA['"${currencysym/&/\&}"']]></string>|' test.xml
Yields
<string name="currencysym"><![CDATA[₹]]></string>
EDIT
As @fedorqui points out, you can use this example to show off correct use of capture groups. You could capture the parts that you want to repeat exactly (the tags), and place them back into the output as-is:
sed 's|\(<string name="currencysym">\)[^<]*\(</string>\)|\1<![CDATA['"${currencysym/&/\&}"']]>\2|' test.xml