Reputation: 2794
I have a config.xml file that has this line in it:
<widget id="com.FitDegree.SOMETHING" version="5.1.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
Using a bash script, I need to replace com.FitDegree.SOMETHING with a string such as com.FitDegree.ThisIsIt
The closest I can get is this:
sed -r 's/\"com\.FitDegree\..+?\"/"com.FitDegree.ThisIsIt"/' ../config.xml > tmpfile
mv tmpfile ../config.xml
but it results in:
<widget id="com.FitDegree.ThisIsIt">
Note: it got rid of all the other things in that line such as version, xmlns etc.
When I test it on a regex tester: https://regex101.com/r/nI8xB8/1 it only selects the com.FitDegree.SOMETHING
Any clue how to fix this?
Upvotes: 1
Views: 1270
Reputation: 36229
This is a risky regex, but often you know, whether the risk is real or only a thinkable one, since the dot matches dots too:
sed 's,com.FitDegree.SOMETHING,com.FitDegree.OtherThing,' sample-2.xml
Your .+\" is greedy and takes the last " as delimiter it can. To make it work, you could define a non matching group for everything, except quotes:
sed -r 's/\"com\.FitDegree\.[^"]+?"/"com.FitDegree.ThisIsIt"/'
# ^^^^ ^no masking needed
Upvotes: 0
Reputation: 1542
I would use a sed character class, with a backreference for simplicity:
sed -e 's/\(\"com\.FitDegree\.\)[^"]*/\1ThisIsIt/' ../config.xml
If you have the option available, you can edit the file in place:
sed -i -e 's/\(\"com\.FitDegree\.\)[^"]*/\1ThisIsIt/' ../config.xml
BTW, Perl handles regular expressions considerably more easily, and this would be:
perl -pe 's/("com\.FitDegree\.).*?"/\1ThisIsIt"/' ../config.xml
And to edit in place:
perl -i -pe 's/("com\.FitDegree\.).*?"/\1ThisIsIt"/' ../config.xml
Upvotes: 0
Reputation: 92854
The right way with xmlstarlet
tool:
xmlstarlet ed -N ns="http://www.w3.org/ns/widgets" \
-u '//ns:widget/@id' -v 'com.FitDegree.ThisIsIt' config.xml
Upvotes: 2