jq сортировка по версии в виде строки

#json #sorting #version #jq

#json #сортировка #версия #jq

Вопрос:

Я пытаюсь отсортировать следующий ответ 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
 

У кого-нибудь есть идея реализовать это? 🙂

Комментарии:

1. 100% правильно. Мой плохой. Но вы идете по идее. 😉

Ответ №1:

Преобразуйте каждый компонент в число, затем отсортируйте по массиву целых чисел.

 jq 'sort_by(.TagVersion|split(".")|map(tonumber))'
 

Вывод:

 [
  {
    "TagVersion": "1.0.9"
  },
  {
    "TagVersion": "1.0.10"
  },
  {
    "TagVersion": "1.0.11"
  },
  {
    "TagVersion": "1.0.77"
  },
  {
    "TagVersion": "1.1.8"
  }
]
 

Комментарии:

1. Это именно то, что я сделал. Но я думал, что это не работает в 100% случаев. В чем здесь магия? tonumber разве он не должен преобразовываться 1.0.77 в 1077 и 1.1.8 в 118 ? 🤔

2. @brcebn: split(".") приводит к ["1", "0", "77"] ; затем map(tonumber) применяется tonumber к каждому элементу, производя [1, 0, 77] . jq знает, как правильно сортировать массив целых чисел, а также как сортировать по единице (как показано в моем выводе).