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、OpenBSD -Vでもデフォルトsortでサポートされていますが、NetBSDではサポートされていません。
クサラナナンダ

FreeBSDも、どうやらそこのmanページにも出力の例があり、OpenBSDのものと同じように見えます。
イルッカチュ

7

チェックアウトsort -V

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

バージョン番号は複雑な獣であり、アルファベット部分を管理する標準はほとんどありませんが、実際のデータでこれを試して、十分かどうかを確認してください。


わあ、すごい!これmayorNumber–minorNumer some textは、Unicode区切り文字のためにフィールドのソートが失敗する、ファイル名に関する私の古い問題に対しても機能します。ヒントをありがとう!
フィリポス

3

これは1行として行うことができますが、ここでは読みやすくするために(パイプで)複数の行に分割し、rc' も処理します。

-V並べ替えのオプションがない場合、または選択する場合でも、ときどきのrc's' に対処する必要があります。

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桁のバージョン管理に4番目の数字を追加し、並べ替えてから再度削除します。動作-これまでで最も簡単なソリューション、私見。

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の後に来るはずです。それがここでの挑戦です。
マンドラゴール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.