Làm cách nào tôi có thể sắp xếp danh sách với cấp độ Major.minor.patch và đôi khi là RC chính xác?


18

Tôi phải sắp xếp danh sách sau đây với tập lệnh shell và làm cho phiên bản mới nhất xuất hiện ở phía dưới hoặc trên cùng. Làm thế nào tôi có thể làm điều đó chỉ với các công cụ shell?

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
Xem thêm printf '%s\n' ${(on)array}trong zsh. (khi danh sách nằm trong $arraymảng).
Stéphane Chazelas

Câu trả lời:


20

GNU sort -Vcó hầu hết có thể xử lý một danh sách như thế ( chi tiết ):

 -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

Tuy nhiên, những .rc*phiên bản đó có thể là một vấn đề, vì có lẽ chúng nên được sắp xếp trước phiên bản không phải là RC tương ứng, nếu có cả hai, đó là. Một số hệ thống phiên bản (như Debian), sử dụng hậu tố bắt đầu bằng dấu ngã ( ~) để đánh dấu các bản phát hành trước và chúng sắp xếp trước phiên bản không có hậu tố, sắp xếp trước các phiên bản có hậu tố khác. Rõ ràng điều này được hỗ trợ bởi ít nhất là sorttrên hệ thống của tôi, như được hiển thị ở trên ( sort (GNU coreutils) 8.23).


3
Bắn tôi vài giây :)
rosuav

1
Cảm ơn rất nhiều. Thậm chí không tưởng tượng rằng loại đó sẽ có một tùy chọn như thế.
Mandragor

FWIW, -Vcũng được hỗ trợ theo mặc định sorttrên OpenBSD, nhưng không phải trên NetBSD.
Kusalananda

FreeBSD cũng vậy, rõ ràng , trang man ở đó cũng có một thứ tự đầu ra ví dụ và trông giống hệt với OpenBSD.
ilkkachu

7

Kiểm tra sort -V:

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

Số phiên bản là những con thú phức tạp, với rất ít tiêu chuẩn chi phối các phần chữ cái, nhưng hãy thử điều này trên dữ liệu thực tế của bạn và xem nó có đủ không.


Woa thật tuyệt! Điều này hoạt động ngay cả đối với một vấn đề cũ của tôi với tên tệp mayorNumber–minorNumer some text, trong đó việc sắp xếp trường không thành công do dấu phân cách unicode. Cảm ơn bạn đã gợi ý!
Philippos

3

Điều này có thể được thực hiện dưới dạng một dòng, nhưng chia thành nhiều dòng (tại các đường ống) ở đây để dễ đọc và xử lý cả rc.

Nếu bạn không có -Vtùy chọn cho loại của mình hoặc thậm chí nếu bạn có, bạn sẽ cần phải xử lý các trường hợp không thường xuyên 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-/"

sedDải đầu tiên loại bỏ các ký tự không phải là số
Sử sortdụng .dấu phân cách ( -t.), sắp xếp số (- n) và phím ( -k)
Cuối cùng sedđặt các ký tự không phải là số trở lại vị trí.


0

Cảm ơn tất cả các nguồn cảm hứng - Tôi có thể đề xuất câu trả lời của riêng tôi: Chương trình sắp xếp có thể bị lừa để làm những gì cần thiết. Cuối cùng, đó là về việc thêm một số thứ tư vào phiên bản 3 chữ số, sắp xếp nó và sau đó loại bỏ nó một lần nữa. Hoạt động - giải pháp đơn giản nhất cho đến nay, IMHO.

cat versionlist |\
sed -r "s/([0-9]+\.[0-9]+\.[0-9]+$)/\1\.99999/"|sort -V|sed s/\.99999$//

kết quả:

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

$

phiên bản 5.0.0 sẽ xuất hiện SAU .rc1 và .rc2 trong danh sách. đó là thách thức ở đây
Mandragor
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.