Как я могу отсортировать список по уровню major.minor.patch и иногда rc правильно?


18

Я должен отсортировать следующий список с помощью сценария оболочки и сделать последнюю версию внизу или вверху. Как бы я сделал это только с инструментами оболочки?

release-5.0.0.rc1
release-5.0.0.rc2
release-5.0.0
release-5.0.1
release-5.0.10
release-5.0.11
release-5.0.13
release-5.0.14
release-5.0.15
release-5.0.16
release-5.0.17
release-5.0.18
release-5.0.19
release-5.0.2
release-5.0.20
release-5.0.21
release-5.0.22
release-5.0.23
release-5.0.24
release-5.0.25
release-5.0.26
release-5.0.27
release-5.0.28
release-5.0.29
release-5.0.3

1
Смотрите также printf '%s\n' ${(on)array}в zsh. (когда список находится в $arrayмассиве).
Стефан

Ответы:


20

У сортировки GNU есть -Vто, что может в основном иметь дело со списком, подобным этому ( подробности ):

 -V, --version-sort
        natural sort of (version) numbers within text

$ cat vers
release-5.0.19
release-5.0.19~pre1
release-5.0.19-bigbugfix
release-5.0.2
release-5.0.20
$ sort -V vers
release-5.0.2
release-5.0.19~pre1
release-5.0.19
release-5.0.19-bigbugfix
release-5.0.20

Тем не менее, эти .rc*версии могут быть проблемой, так как они, вероятно, должны быть отсортированы перед соответствующей версией без rc, если таковые были, то есть. Некоторые системы управления версиями (например, Debian) используют суффиксы, начинающиеся с tilde ( ~), чтобы пометить предварительные выпуски, и они сортируют перед версией без суффикса, который сортирует перед версиями с другими суффиксами. Очевидно, это поддерживается по крайней мере в sortмоей системе, как показано выше ( sort (GNU coreutils) 8.23).


3
Отрезал мне пару секунд :)
rosuav

1
Большое спасибо. Даже не предполагал, что у такого рода будет такая возможность.
Мандрагор

FWIW, -Vтакже поддерживается по умолчанию sortв OpenBSD, но не в NetBSD.
Кусалананда

Во FreeBSD, по-видимому , страница руководства также имеет пример порядка вывода и выглядит идентично OpenBSD.
ilkkachu

7

Проверьте sort -V:

   -V, --version-sort
          natural sort of (version) numbers within text

Номера версий - сложные звери, с очень немногими стандартами, управляющими буквенными частями, но попробуйте это на ваших реальных данных и посмотрите, достаточно ли это.


Вау, отлично! Это работает даже для моей старой проблемы с именами файлов mayorNumber–minorNumer some text, где сортировка полей не выполняется из-за разграничителя Юникода. Спасибо за подсказку!
Филиппос

3

Это можно сделать одной строкой, но разделить ее на несколько строк (в каналах) здесь для удобства чтения, и также обрабатывает rcбуквы.

Если у вас нет -Vвыбора для вашего вида, или даже если у вас есть, вам придется иметь дело с случайными rc:

cat versionlist |
sed -e "s/release-//" -e "s/rc//" |
sort -t. -n -k1,1 -k2,2 -k3,3 -k4,4 |
sed -r -e "s/([^.]+)\.([^.]+)\.([^.]+)\.([^.]+)/\1.\2.\3.rc\4/" -e "s/^/release-/"

Первый sedудаляет нечисловые символы
. sortИспользует .разделитель ( -t.), числовую сортировку (- n) и ключи ( -k).
В последнем sedслучае нецифровые символы возвращаются на место.


0

Спасибо за все вдохновение - позвольте мне предложить свой ответ: программу сортировки можно обмануть, чтобы сделать то, что нужно. В конце концов, речь идет о добавлении четвертого числа к 3-значному версионированию, сортировке и последующему удалению. Работает - самое простое решение до сих пор, ИМХО.

cat versionlist |\
sed -r "s/([0-9]+\.[0-9]+\.[0-9]+$)/\1\.99999/"|sort -V|sed s/\.99999$//

результат:

release-5.0.0.rc1
release-5.0.0.rc2
release-5.0.0

....

0
$ cat /tmp/tmp.tmp
release-5.0.0.rc1
release-5.0.0.rc2
release-5.0.0
release-5.0.1
release-5.0.10
release-5.0.11
release-5.0.13
release-5.0.14
release-5.0.15
release-5.0.16
release-5.0.17
release-5.0.18
release-5.0.19
release-5.0.2
release-5.0.20
release-5.0.21
release-5.0.22
release-5.0.23
release-5.0.24
release-5.0.25
release-5.0.26
release-5.0.27
release-5.0.28
release-5.0.29
release-5.0.3

$ cat /tmp/tmp.tmp | awk -F\- '{ print $2,$1 }' | sort -n | awk '{ print $2 "-" $1 }'
release-5.0.0
release-5.0.0.rc1
release-5.0.0.rc2
release-5.0.1
release-5.0.10
release-5.0.11
release-5.0.13
release-5.0.14
release-5.0.15
release-5.0.16
release-5.0.17
release-5.0.18
release-5.0.19
release-5.0.2
release-5.0.20
release-5.0.21
release-5.0.22
release-5.0.23
release-5.0.24
release-5.0.25
release-5.0.26
release-5.0.27
release-5.0.28
release-5.0.29
release-5.0.3

$

Release-5.0.0 должен появиться ПОСЛЕ .rc1 и .rc2 в списке. это проблема здесь.
Мандрагор
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.