tags:

views:

41

answers:

4

I have a text file with entries representing build tags with version and build number in the same format as debian packages like this:

nimbox-apexer_1.0.0-12
nimbox-apexer_1.1.0-2
nimbox-apexer_1.1.0-1
nimbox-apexer_1.0.0-13 

Using a shell script I need to sort the above list by 'version-build' and get the last line, which in the above example is nimbox-apexer_1.1.0-2.

+1  A: 

Get the latest build with:

cat file.txt | sort -V | tail -n1

Now, to catch it into a variable:

BUILD=$(cat file.txt | sort -V | tail -n1)
polemon
If I introduce `nimbox-apexer_1.10.0-9` and `nimbox-apexer_1.9.0-1` in the list it provides the wrong result `nimbox-apexer_1.9.0-1` when it should be `nimbox-apexer_1.10.0-9` which is really the **latest** version.
rmarimon
No need for `cat`.
Dennis Williamson
@marimon my bad, vorgot the -V switch, that I added just now.@Dennis Williamson, right, I just like using it that way...
polemon
Nice, if you have a recent enough version of GNU sort.
Jonathan Leffler
@Jonathan Leffler: Does it need to be that recent? I've been using it like that for a couple of years, iirc.
polemon
It needs to be more recent than the `sort` on the Linux box I'm using at the office - that does not support it. However, although recently upgraded from an even more archaic version of Linux, the box is not what I'd regard as current (I think it is RHEL5: `2.6.18-128.el5 #1 SMP Wed Dec 17 11:41:38 EST 2008`).
Jonathan Leffler
+1  A: 
sort -n -t "_" -k2.3 file | tail -1
ghostdog74
I don't understand fully the -n flag but having two periods does seem to be confusing. If I include `nimbox-apexer_11.9.0-2` in the list it doesn't work as expected.
rmarimon
I assume that is why the k2.3 is included so that sorting happens after the first `1.`.
rmarimon
A: 

With GNU sort:

sort --version-sort file | tail -n -1

GNU tail doesn't like tail -1.

Dennis Williamson
I need to be running this script on linux and mac osx... so gnu sort would not work for me in the general way.
rmarimon
A: 

I haven't been able to find a simple way to do this. I've been looking at code to sort ip address, which is similar to my problem, and trying to change my situation to that one. This what I have come up with. Please tell me there is a simpler better way !!!

sed 's/^[^0-9]*\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)-\([0-9]*\)/\1.\2.\3.\4 &/' list.txt | \
  sort -t . -n -k 1,1 -k 2,2 -k 3,3 -k 4,4 | \
  sed 's/^[^ ]* \(.*\)/\1/' | \
  tail -n 1

So starting with this data:

nimbox-apexer_11.9.0-2
nimbox-apexer_1.10.0-9
nimbox-apexer_1.9.0-1
nimbox-apexer_1.0.0-12
nimbox-apexer_1.1.0-2
nimbox-apexer_1.1.0-1
nimbox-apexer_1.0.0-13

The first sed converts my problem into a sorting IPs problem keeping the original line to reverse the change at the end:

11.9.0.2 nimbox-apexer_11.9.0-2
1.10.0.9 nimbox-apexer_1.10.0-9
1.9.0.1 nimbox-apexer_1.9.0-1
1.0.0.12 nimbox-apexer_1.0.0-12
1.1.0.2 nimbox-apexer_1.1.0-2
1.1.0.1 nimbox-apexer_1.1.0-1
1.0.0.13 nimbox-apexer_1.0.0-13 

The sort orders the line using the first four numbers which in my case represent mayor.minor.release.build

1.0.0.12 nimbox-apexer_1.0.0-12
1.0.0.13 nimbox-apexer_1.0.0-13 
1.1.0.1 nimbox-apexer_1.1.0-1
1.1.0.2 nimbox-apexer_1.1.0-2
1.9.0.1 nimbox-apexer_1.9.0-1
1.10.0.9 nimbox-apexer_1.10.0-9
11.9.0.2 nimbox-apexer_11.9.0-2

The last sed eliminates the data used to sort

nimbox-apexer_1.0.0-12
nimbox-apexer_1.0.0-13 
nimbox-apexer_1.1.0-1
nimbox-apexer_1.1.0-2
nimbox-apexer_1.9.0-1
nimbox-apexer_1.10.0-9
nimbox-apexer_11.9.0-2

Finally tail gets the last line which is the one I need.

rmarimon