Вот мой файл JSON test.json
:
[
{
"name": "nodejs",
"version": "0.1.21",
"apiVersion": "v1"
},
{
"name": "nodejs",
"version": "0.1.20",
"apiVersion": "v1"
},
{
"name": "nodejs",
"version": "0.1.11",
"apiVersion": "v1"
},
{
"name": "nodejs",
"version": "0.1.9",
"apiVersion": "v1"
},
{
"name": "nodejs",
"version": "0.1.8",
"apiVersion": "v1"
}
]
Когда я использую max_by
, jq
возвращает 0.1.9
вместо 0.1.21
, вероятно, из-за значения в кавычках:
cat test.json | jq 'max_by(.version)'
{
"name": "nodejs",
"version": "0.1.9",
"apiVersion": "v1"
}
Как я могу получить элемент с версией = 0.1.21?
Сравнение Семантическая версия изначально не поддерживается в jq
. Вам нужно поиграть с полями, разделенными на .
jq 'sort_by(.version | split(".") | map(tonumber))[-1]'
split(".")
берет строку из .version
и создает массив полей, то есть 0.1.21
становится массивом [ "0", "1", "21"]
, а map(tonumber)
берет входной массив и преобразует элементы строки в массив цифр.
Функция sort_by()
выполняет индексное сравнение для каждого из элементов в массиве, сгенерированном на последнем шаге, и сортирует в порядке возрастания с объектом, содержащим версию 0.1.21
последним. Обозначение [-1]
состоит в том, чтобы получить последний объект из этого отсортированного массива.
Можно было бы просто использовать max_by
.
Вот адаптация более общего ответа с использованием jq в Как отсортировать результаты поиска пакетов Artifactory по номеру версии с помощью JFrog CLI?
def parse:
[splits("[-.]")]
| map(tonumber? // .) ;
max_by(.version|parse)
Как менее надежный однострочный:
max_by(.version | [splits("[.]")] | map(tonumber))
это также полезно для сортировки адресов ipv4. я застрял, пытаясь отсортировать адрес ipv6, нет «tobase16»
@Greg - см. rosettacode.org/wiki/Non-decimal_radices/Convert#jq
Приятно! Благодарю. Кстати, чтобы заставить эту однострочную работу работать, мне пришлось добавить: max_by(.version|[splits("[.]")] | map(tonumber))
@грег: исправлено. Спасибо.
хороший однострочный ответ. Я тестировал с другими значениями, такими как
0.2.1
или11.7
, и это работает во всех случаях. Спасибо