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배열 에있을 때 ).
Stéphane Chazelas

답변:


20

GNU 정렬은 -V대부분 다음과 같은 목록을 처리 할 수 ​​있습니다 ( details ).

 -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 버전 보다 먼저 정렬 해야하기 때문입니다. 데비안과 같은 일부 버전 관리 시스템에서는 물결표 ( ~)로 시작하는 접미사를 사용 하여 시험판을 표시하고 접미사없이 버전보다 먼저 정렬합니다.이 접미사는 다른 접미사가있는 버전보다 먼저 정렬됩니다. 분명히 이것은 sort위 ( sort (GNU coreutils) 8.23) 와 같이 적어도 내 시스템 에서 지원됩니다 .


3
:)
rosuav

1
고마워 그런 종류의 옵션이 그렇게 될 것이라고 상상조차하지 못했습니다.
Mandragor

FBSD 는 OpenBSD -V에서도 기본적 sort으로 지원 되지만 NetBSD에서는 지원 되지 않습니다.
Kusalananda

FreeBSD도 역시 매뉴얼 페이지에 예제 출력 순서가 있으며 OpenBSD와 동일하게 보입니다.
ilkkachu

7

체크 아웃 sort -V:

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

버전 번호는 알파벳 부분을 제어하는 ​​표준이 거의없는 복잡한 짐승이지만 실제 데이터에서 시도하여 충분한 지 확인하십시오.


와우! 이것은 mayorNumber–minorNumer some text유니 코드 구분 기호로 인해 필드 정렬이 실패 하는 파일 이름이있는 오래된 문제에서도 작동합니다 . 힌트 주셔서 감사합니다!
Philippos

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

모든 영감을 가져 주셔서 감사합니다-나 자신의 대답을 제안 할 수 있습니다 : 정렬 프로그램은 필요한 일을하도록 속일 수 있습니다. 결국 세 번째 숫자 버전에 네 번째 숫자를 추가하고 정렬 한 다음 다시 제거해야합니다. 작동-지금까지 가장 간단한 솔루션, IMHO.

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 뒤에 있어야합니다. 그것이 여기의 도전입니다.
Mandragor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.