3

I have a pom file that has the following information:

<modelVersion>4.0.0</modelVersion>
  <groupId>com.site.camera</groupId>
  <artifactId>proj3</artifactId>
  <packaging>pom</packaging>
  <version>2.6</version>
  <name>Proj 3</name>

I am writing a bash script and want to be able to open this file (pom.xml) and cut out the version (eg. 2.6 in this case). I am doing this because as I update the version I want the rest of my script to update with it.

Things that I have tried:

var=$(grep <version>2.6</version> pom.xml)
echo $var

Note that I have multiple version parameters in the pom file. And I need this specific version which is surrounded with this name, packaging, artifactId etc.

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
Alex Thomson
  • 143
  • 1
  • 3
  • 10
  • 1
    Possible duplicate of [How to get Maven project version to the bash command line](http://stackoverflow.com/questions/3545292/how-to-get-maven-project-version-to-the-bash-command-line) – broc.seib Jan 16 '17 at 21:43

7 Answers7

8

Some people object to parsing XML with regex. Here's how you can do it correctly and robustly with xmlstarlet:

$ cat pom.xml 
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.site.camera</groupId>
  <artifactId>proj3</artifactId>
  <packaging>pom</packaging>
  <version>2.6</version>
  <name>Proj 3</name>
</project>

$ xmlstarlet sel -t -v '/project/version' pom.xml 
2.6

This works equally well after XML tools and editors have had their way with your document:

$ cat pom.xml 
<project>
  <version><![CDATA[2]]>&#x002E;6
  </version>
</project>

$ xmlstarlet sel -t -v '/project/version' pom.xml 
2.6

Edit: As a testament to Doing It Right(tm), this solution still works fine after it was pointed out that there will be a lot of different version tags.

Community
  • 1
  • 1
that other guy
  • 116,971
  • 11
  • 170
  • 194
  • Other people might object to parsing maven configuration using DOM :) +1. But I have another solution. – Vytenis Bivainis Apr 02 '15 at 20:09
  • 1
    When the pom file starts with a ``, the select statement requires to define the namespace as well. I've added an [answer](https://stackoverflow.com/a/70003714/1076463) illustrating this. – Robin Nov 17 '21 at 11:40
6

Using maven you do it this way:

echo '${project.version}' | mvn help:evaluate | grep -v '^[[]'
Vytenis Bivainis
  • 2,308
  • 21
  • 28
  • Very nice. Sadly none of `-q`, `-l /dev/null` or `2> /dev/null` will convince `mvn` to separate output from buildlog, so the grep seems to be the only way. – that other guy Apr 02 '15 at 20:31
3

try like this:

var=$(grep -Po '<version>\K[^<]*' pom.xml)
echo $var

output:

2.6
  • -P : use perl regexp format
  • -o : print matching part only
Chris Maes
  • 35,025
  • 12
  • 111
  • 136
2

The simplest way is to use GNU grep's perl-compatible regexes

grep -oP '<version>\K[^<]+' pom.xml

With sed, you'd write

sed -n 's/^[[:blank:]]*<version>\([^<]\+\).*/\1/p' pom.xml

Thanks to David W.'s thoughtful commentary: the solution must use an XML parser. xmlstarlet is one such tool:

ver=$( xmlstarlet sel -t -v /project/version pom.xml )

And just to be different, ruby comes with an XML parser in its standard library:

ruby -r rexml/document -e 'puts REXML::Document.new(File.new(ARGV.shift)).elements["/project/version"].text' pom.xml
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • 1
    What if there are other lines with a version number in the pom? Every dependency and plugin will have a version number. – David W. Apr 02 '15 at 19:12
  • The `` attribute is found all throughout the `pom.xml`. Take a look at this one for [commons-lang3](http://search.maven.org/#artifactdetails%7Corg.apache.commons%7Ccommons-lang3%7C3.3.2%7Cjar). There's a parent ``, an artifact ``, and three dependencies with ``. There are five in the `` section and 2 more in the `` section. This grep will pick them all up. – David W. Apr 02 '15 at 20:04
  • 1
    xmlstarlet line didn't work for me, instead it did pretty well -> version=$( xmlstarlet sel -t -v '/_:project/_:version' pom.xml ) – Federico Gaule Palombarani May 31 '16 at 15:55
2

The answer from that other guy illustrates the correct approach of using an xml parser, but it cannot deal with namespaces in the pom.xml file.

If your POM file starts like this:

<?xml version="1.0" encoding="UTF-8" ?>
<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                             http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
 ...
</project>

you'll need to add the namespace when using xmlstarlet:

xmlstarlet select \
  -N x="http://maven.apache.org/POM/4.0.0" \
  --template --value-of "/x:project/x:version" \
  pom.xml
Robin
  • 36,233
  • 5
  • 47
  • 99
1

Or without perl compatible regular expressions using parameter expansion/substring extraction:

$ var=$(grep '<version>' pom.xml); ver=${var%<*}; ver=${ver#*>}; echo $ver
2.6

I would prefer the perl compatibile RE if you have that available.

Note: As pointed out by David W. this works for the example given, but will return multiple version strings if the input file has more than one line containing <version>. The full pom.xml file referenced below in the comments contains multiple <version> strings. An additional loop will be required to process all version lines and without a unique tag, it is not possible to determine which version is the desired version. For example parsing the current full pom.xml with:

$ for i in $(grep '<version>' pom.xml); do ver=${i%<*}; ver=${ver#*>}; echo "version: $ver"; done

Returns:

version: 33
version: 3.3.2
version: 4.11
version: 2.4
version: 3.2
version: 2.9.1
version: 2.5.2
version: 2.5.1
version: 2.4
version: 3.0.1
version: 2.4
version: 2.0
version: 1.7
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Look at the `pom.xml` for [commons-lang3](http://search.maven.org/#artifactdetails%7Corg.apache.commons%7Ccommons-lang3%7C3.3.2%7Cjar). There are almost a dozen `` elements your `grep` will pick up. – David W. Apr 02 '15 at 20:05
  • Well, that does change things a bit! I was just going by the example given. Thanks for the heads up. I'll see if it is salvagable, if not I'll note it. – David C. Rankin Apr 02 '15 at 20:11
0

My Requirement was also similar. We are using SNAPSHOT at the end of our version so I did this to find out the Version number (Extension of David's answer)

for i in $(grep '<version>' pom.xml); do
    #echo "$i"; 
    ver=${i%<*}; 
    ver=${ver#*>};
    if [[ $ver == *"SNAPSHOT"* ]]
        then
            echo "$ver";
    fi 

done

And It gives me an output; Which I wanted

1.09-SNAPSHOT

Tiwari
  • 329
  • 2
  • 7