0

I have the following string in a file:

<Product Id="*" Name="NAME" Language="1033" Version="1.2.3.4" Manufacturer="Manufacturer" UpgradeCode="12345">

I want to replace the last number field in the version value (i.e. "4") using bash command (sed?) with a new number. I want to be able to change this to any other number that I pass. I tried using:

sed -i -e "s#Version=\"\([0-9]\)\.\([0-9]+\)\.\([0-9]+\)\.\([0-9]+\)\"#Version=\"\1\.\2\.\3\.10\"#g" <filename>

but this didn't work.

2
  • While it is possible to update XML using sed, it's really not the best tool for the task unless you've got nothing else. Which is unlikely, considering you're dealing with XML to begin with. Commented Sep 15, 2015 at 9:19
  • I only need to change the version number within a bash script. Commented Sep 15, 2015 at 10:10

3 Answers 3

3

give this sed line a try:

update

fix:

sed -r 's/(.*Version="[^"]*[.])[^."]+(".*)/\1foo\2/ file

the above line change the last 4 into foo. You just change the foo to your desired value.

Sign up to request clarification or add additional context in comments.

7 Comments

This doesn't always work for large number? Appends for large numbers.
@WahajAli They didn't include the . so it only get the last character before the quotes. Use sed -r 's/(.*Version="[^"]*\.)[^."]+(".*)/\1foo\2/'
This should work also fo large number. Which one failed in your test ?
@999999999999999999999999999999 This is not the same, in your case you must have at least a . and not in Kent one but both works
@WahajAli a [.] was missing.. sorry, fixed in answer.
|
1

If you have gnu-awk, you can do yhis:

awk -v n=8 '{print gensub(/(Version="[0-9.]+\.)[0-9]+"/, "\\1" n "\"", "1")}' file
<Product Id="*" Name="NAME" Language="1033" Version="1.2.3.8" Manufacturer="Manufacturer" UpgradeCode="12345">

Where n is the version # you want to update in the file.

Comments

1

Assuming:

  • (cfr @999999999999999999999999999999) there is at least 1 dot in the version (needed to increment or modify by definition)
  • it have only 1 version to change by line, and line is the good one (no preselection nor separation where XML allow several "tag" per line) and not spread on several line
  • I use [[:alnum:]] class instead of only [[:digit:]] allowing letter in version like beta, ...

sed 's/\([[:blank:]]Version="[^"]*[.]\)[[:alnum:]]*"/\1YourNumber"/' YourFile

4 Comments

If you wanted to provide a case for both if it includes a . and not you could us sed -r 's/(.*Version=")([^."]*|([^"]+\.)[^."]+)(".*)/\1\3foo\4/'
i try to stay posix compliant, so reusable everywhere (no |). Without my consraint, you are right
I thought the bar was posix compliant. It says Alternation is supported through the usual vertical bar |. on here. Also the formatting in your answer is messed up somehow.
| is not a OR in posix version (nor escaped version). The sed posix is realy basic (less than grep BRE)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.