Major.minor.patch 수준 및 때로는 rc 수준으로 목록을 올바르게 정렬하는 방법은 무엇입니까?

Major.minor.patch 수준 및 때로는 rc 수준으로 목록을 올바르게 정렬하는 방법은 무엇입니까?

다음 목록을 정렬하고 최신 버전이 맨 아래 또는 맨 위에 표시되도록 하려면 쉘 스크립트를 사용해야 합니다. 쉘 도구만 사용하여 이 작업을 어떻게 수행할 수 있습니까?

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

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).

예제 목록을 정렬하려면 다음 명령을 사용할 수 있습니다.

perl -pe 's/\.(?=rc)/~/' < versions.txt | sort -V | perl -pe 's/~/./' > versions-sorted.txt

답변2

확인하다 sort -V:

   -V, --version-sort
          natural sort of (version) numbers within 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사용해야 합니다.구분 기호( ), 숫자 정렬( ), 필드 1, 2, 3, 4를 키로 열거( )합니다.-t.-n-k
  • 마지막으로 sed숫자가 아닌 문자를 다시 제자리에 놓습니다(가정).모든입력의 행에 해당 내용이 있습니다).

답변4

귀하의 예에서는 이것이 작동합니다. |적용하기 전에 각 줄에 후행을 추가한 다음 sort -V후행을 제거합니다 |. 그 이유는 sort -V명령이 를 |제외한 모든 ASCII 문자 뒤에 오기 때문입니다 }.

$ cat versions.txt | sed 's/$/|/' | sort -V | sed 's/|$//'

release-5.0.0.rc1
release-5.0.0.rc2
release-5.0.0
release-5.0.1
release-5.0.2
release-5.0.10
release-5.0.11

release-5.0.0.rc그러나 목록에 추가되면 더 복잡한 명령이 필요합니다. 이렇게 하면 (또는 해당 문제에 대한 다른 항목) 없는 줄에만 release-후행이 일시적으로 제거되고 추가 됩니다.|rc[a-zA-Z]

$ cat versions.txt | 
sed -e 's/^release-//' -e '/[a-zA-Z]/! s/$/|/' | 
sort -V | 
sed -e 's/^/release-/' -e 's/|$//'

release-5.0.0.rc
release-5.0.0.rc1
release-5.0.0.rc2
release-5.0.0
release-5.0.1
release-5.0.2
release-5.0.10
release-5.0.11

관련 정보