-
-
Save andkirby/54204328823febad9d34422427b1937b to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash | |
# Download this gist | |
# curl -Ls https://gist.github.com/andkirby/54204328823febad9d34422427b1937b/raw/semversort.sh | bash | |
# And run: | |
# $ semversort 1.0 1.0-rc 1.0-patch 1.0-alpha | |
# or in GIT | |
# $ semversort $(git tag) | |
# Using pipeline: | |
# $ echo 1.0 1.0-rc 1.0-patch 1.0-alpha | semversort | |
# | |
# 2016-11-03 | |
# Released. | |
# 2020-03-10 | |
# Changed regular part from "[A-z]" to "[A-Za-z]" | |
set -o errexit | |
set -o pipefail | |
set -o nounset | |
#set -o xtrace | |
# Script running with pipeline | |
if [ -z "${BASH_SOURCE[0]:-}" ]; then | |
__dir=/usr/local/bin | |
if [ ! -d ${__dir} ]; then | |
__dir=/usr/bin | |
fi | |
__file=${__dir}/semversort | |
curl -Ls https://gist.github.com/andkirby/54204328823febad9d34422427b1937b/raw/semversort.sh -o ${__file} && \ | |
chmod u+x ${__file} && \ | |
echo 'Semantic version sort: '${__file} && \ | |
exit 0 | |
exit 1 | |
fi | |
if [ -t 0 ]; then | |
versions_list=$@ | |
else | |
# catch pipeline output | |
versions_list=$(cat) | |
fi | |
version_weight () { | |
echo -e "$1" | tr ' ' "\n" | sed -e 's:\+.*$::' | sed -e 's:^v::' | \ | |
sed -re 's:^[0-9]+(\.[0-9]+)+$:&-stable:' | \ | |
sed -re 's:([^A-Za-z])dev\.?([^A-Za-z]|$):\1.10.\2:g' | \ | |
sed -re 's:([^A-Za-z])(alpha|a)\.?([^A-Za-z]|$):\1.20.\3:g' | \ | |
sed -re 's:([^A-Za-z])(beta|b)\.?([^A-Za-z]|$):\1.30.\3:g' | \ | |
sed -re 's:([^A-Za-z])(rc|RC)\.?([^A-Za-z]|$)?:\1.40.\3:g' | \ | |
sed -re 's:([^A-Za-z])stable\.?([^A-Za-z]|$):\1.50.\2:g' | \ | |
sed -re 's:([^A-Za-z])pl\.?([^A-Za-z]|$):\1.60.\2:g' | \ | |
sed -re 's:([^A-Za-z])(patch|p)\.?([^A-Za-z]|$):\1.70.\3:g' | \ | |
sed -r 's:\.{2,}:.:' | \ | |
sed -r 's:\.$::' | \ | |
sed -r 's:-\.:.:' | |
} | |
tags_orig=(${versions_list}) | |
tags_weight=( $(version_weight "${tags_orig[*]}") ) | |
keys=$(for ix in ${!tags_weight[*]}; do | |
printf "%s+%s\n" "${tags_weight[${ix}]}" ${ix} | |
done | sort -V | cut -d+ -f2) | |
for ix in ${keys}; do | |
printf "%s\n" ${tags_orig[${ix}]} | |
done |
@mfilotto had the same problem, substituting "[^A-z]" with "[^a-zA-Z]" did the trick for me (Centos 7 sed 4.2.2).
$ curl -Ls https://gist.github.com/andkirby/54204328823febad9d34422427b1937b/raw/semversort.sh | bash
Semantic version sort: /usr/local/bin/semversort
$ curl -s https://api.github.com/repos/glpi-project/glpi/releases | jq --raw-output '.[] | .tag_name' | sort --reverse | /usr/local/bin/semversort
sed: -e expression #1, char 36: Invalid range end
sed: -e expression #1, char 43: Invalid range end
sed: -e expression #1, char 40: Invalid range end
sed: -e expression #1, char 42: Invalid range end
sed: -e expression #1, char 42: Invalid range end
sed: -e expression #1, char 37: Invalid range end
sed: -e expression #1, char 43: Invalid range end
$ sed --version
sed (GNU sed) 4.2.2
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Jay Fenlason, Tom Lord, Ken Pizzini,
and Paolo Bonzini.
GNU sed home page: http://www.gnu.org/software/sed/.
General help using GNU software: http://www.gnu.org/gethelp/.
E-mail bug reports to: [email protected].
Be sure to include the word sed'' somewhere in the
Subject:'' field.
With patch [^A-z] -> [^a-zA-Z] , is running, but x.x, beta and RC version are in wrong order:
curl -s https://api.github.com/repos/glpi-project/glpi/releases | jq --raw-output '.[] | .tag_name' | /usr/local/bin/semversort
0.85.4
0.85.5
0.90.1
0.90.2
0.90.3
0.90.4
0.90.5
0.90
9.1.1
9.1.2
9.1.3
9.1.4
9.1.5
9.1.6
9.1.7.1
9.1
9.2.1
9.2.2
9.2.3
9.2.4
9.2-RC2
9.2
9.3.0
9.3-beta
9.3-RC1
9.3-RC2
@leifhetle thanks for this note.
@Wolvverine, yeah, it doesn't work. But it works with this one:
https://gist.github.com/andkirby/0046df5cad44f86b670a102b7c8b7ba7/raw/version_sort_install.sh
Yeah, that's PHP function. Seems it's not what you are looking for.
Just tested sed original script on Ubuntu - it does work
# sed --version
sed (GNU sed) 4.4
How about just sort -V
? :)
-V, --version-sort
natural sort of (version) numbers within text
@waja here is Stack Overflow thread:
It might help you find a proper solution which might work for you.
But in a nutshell, no, "sort -V" does not work (as initially I was needed to use -patch suffixes), you may see it in this answer.
This script produces wrong result.
Example:
$ (echo 0.5; echo 0.5.1; echo 0.5.2) | semversort.sh
0.5.1
0.5.2
0.5
@yurivict yes, it's not intended to use various formats, but only Semantic Versions format which is MAJOR.MINOR.PATCH.
Like it described in https://semver.org/
Thanks for this note anyway, it's good to know edge cases.
@mfilotto
Oh, buddy, sorry for the silence. Perhaps, you have another version
sed
or I made a bug. :)Were you able to make the fix?