Як я можу сортувати список за рівнем 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) використовують суфікси, що починаються з тильди ( ~), щоб позначити попередні випуски, і вони сортують перед версією без суфікса, який сортує перед версіями з іншими суфіксами. Мабуть, це підтримується принаймні в sortмоїй системі, як показано вище ( sort (GNU coreutils) 8.23).


3
Обстріляв мене пару секунд :)
rosuav

1
Дуже дякую. Навіть не уявляв, що такий варіант матиме такий варіант.
Мандрагор

FWIW, -Vтакож підтримується за замовчуванням sortна OpenBSD, але не на NetBSD.
Kusalananda

FreeBSD також, мабуть , сторінка man також має приклад порядку виведення, і виглядає ідентично OpenBSD.
ilkkachu

7

Перевірте sort -V:

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

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


Ого, чудово! Це працює навіть для старої проблеми шахти з іменами файлів mayorNumber–minorNumer some text, де сортування поля не вдається через розмежувач Unicode. Дякую за підказку!
Філіпос

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

Дякую за все натхнення - чи можу я запропонувати власну відповідь: Програму сортування можна підманути робити те, що потрібно. Зрештою, мова йде про додавання четвертого числа до тризначної версії, відсортуйте його та знову видаліть. Роботи - найпростіше рішення поки що, ІМХО.

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.