我正在尝试对以下json响应进行排序,以选择最新版本:
[
{
"TagVersion": "1.0.11"
},
{
"TagVersion": "1.1.8"
},
{
"TagVersion": "1.0.10",
},
{
"TagVersion": "1.0.9",
},
{
"TagVersion": "1.0.77"
}
]
正确排序应为:
{
"TagVersion": "1.0.9",
},
{
"TagVersion": "1.0.10",
},
{
"TagVersion": "1.0.11"
},
{
"TagVersion": "1.0.77"
},
{
"TagVersion": "1.1.8"
}
我目前可以做部分工作,它只适用于简单的情况(所有版本的部件major/minor/bug具有相同的位数)。jq -r [.[]]|max_by(.TagVersion|split(".") | map(tonumber)
在我看来,最好的方法应该是在每一部分加上一个乘法。例如:
# With condition than every "part" as a maximum of 2 digits. It won't work with 3 digits
# Version 1.23.87
1 * 1000 + 23 * 10 + 87 = 1317
# Version 3.0.0
1 * 1000 + 0 * 10 + 0 = 3000
# Version 1.89.78
1 * 1000 + 89*10 + 78 = 1968
有人有办法实现这个吗?🙂
2条答案
按热度按时间hyrbngr71#
将每个组件转换为数字,然后对整数数组进行排序。
输出:
zte4gxcn2#
这允许您使用包括
-pre.release
后缀在内的完整Semantic Versioning 2.0排序。由于它使用了一些技巧,我可以解释一下,一般来说,
semver_cmp
函数将版本字符串转换成一个2级数组,jq
可以根据需要对该数组进行本地排序,该数组如下所示:sub("\\+.*$"; "")
会去除任何不参与比较的最终元数据。index("-") as $i
查找表示预发行后缀的短划线-
的第一个位置。我没有使用
split("-")
,因为后面允许使用破折号,我不想以后使用join("-")
。[.[:$i], if $i != null then .[$i+1:] else empty end]
将x.y.z
放入数组中,如果找到-
,则将后缀放在它旁边。map(split(".") | map(opt(tonumber)))
将这些元素按.
拆分,并在可能的情况下将“标识符”转换为数字。.[1] |= (.//{})
是一个小技巧,它添加一个空对象作为没有后缀的纯文本字符串的第二个元素。对象按照数组排序,这就是我们这里需要的。整理好后,输入如下:
将正确地结束像这样-与普通版本排序后,预发布。