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

これは1行で行うことができますが、読みやすくするためにパイプから複数行に分割し、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

関連情報