2

I have a XML file that has a version number in the following format:

<Product Id="*" Name="Name" Language="1033" Version="1.2.3.4">

I want to find the last number in the version string (i.e. "4" in this example) and then increment it by one - replacing it in the file. Ideally using simple bash commands (AWK?).

4
  • So 1.2.3.9 should become 1.2.4.0 ? Commented Sep 12, 2015 at 17:59
  • No, I just want to increment it continuously. Commented Sep 12, 2015 at 18:23
  • do you only want to bump the last number in the version string? but what if you want to bump the minor-version (1.2.3.9 -> 1.3.0.0)? Commented Sep 12, 2015 at 18:44
  • For minor upgrades I would do a manual build. For the patch builds, I've had them automated for my particular use case. Commented Sep 12, 2015 at 18:47

4 Answers 4

5

You may use perl.

perl -i -pe 's/\b(\d+)(?=\D*$)/$1+1/e' file

or

perl -i -pe 's/\bVersion="[^"]*\K\b(\d+)(?=[^"]*")/$1+1/e' file

Example:

$ echo '<Product Id="*" Name="Name" Language="1033" Version="1.2.3.4">' | perl -pe 's/\b(\d+)(?=\D*$)/$1+1/e'
<Product Id="*" Name="Name" Language="1033" Version="1.2.3.5">
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks. This seems to increment another number later in the file, and skips the version field altogether.
You the one said the last number. You didn't talk about the version. Check my update.
Sorry, I meant the last number for the version field, i.e. 1.2.3.4. I tried the second command but that removes the Version="1.2.3.4" and replaces it with 5"
forget to add \K, check now.
1

Assuming your file is called version.xml, you can try the following:

CURRENT=$(awk -F'"' '{print $8}' version.xml)
NEXT=$(echo ${CURRENT}|awk -F. '{print $1"."$2"."$3"."$4+1}')
sed "s/Version.*/Version=\"${NEXT}\">/g" version.xml

Comments

1

Here is an awk command that should work on non-gnu awk (BSD) versions as well:

s='<Product Id="*" Name="Name" Language="1033" Version="1.2.3.9">'

awk -F '[="]+' '{
   for(i=1; i<=NF; i++)
      if ($(i-1) == " Version") {
           n = split($i, vers, ".");
           sub(/\.[0-9]+"/, "." vers[n]+1 "\"")
      }
} 1' <<< "$s"

Output:

<Product Id="*" Name="Name" Language="1033" Version="1.2.3.10">

Comments

0

I can try with awk match and gsub functions

echo '<Product Id="*" Name="Name" Language="1033" Version="1.2.3.4">' |
awk '{
  match($0, /\.([0-9]+)([^0-9]*)$/, a); 
  gsub(/\.([0-9]+)[^0-9]*$/,"." a[1]+1 a[2]); 
  print;
}'

you get

<Product Id="*" Name="Name" Language="1033" Version="1.2.3.5">

if input is, for example:

<Product Id="*" Name="Name" Language="1033" Version="1.2.3.99">

output is:

<Product Id="*" Name="Name" Language="1033" Version="1.2.3.100">

Comments

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.