ฉันจะเรียงลำดับรายการด้วยระดับ 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ส่วนใหญ่ที่สามารถจัดการกับรายการเช่นนั้น ( รายละเอียด ):

 -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's) ให้ใช้คำต่อท้ายที่เริ่มต้นด้วยเครื่องหมายตัวหนอน ( ~) เพื่อทำเครื่องหมายก่อนเผยแพร่และพวกเขาเรียงลำดับรุ่นก่อนหน้าโดยไม่มีคำต่อท้าย เห็นได้ชัดว่าสิ่งนี้ได้รับการสนับสนุนจากsortระบบของฉันอย่างน้อยดังที่แสดงด้านบน ( sort (GNU coreutils) 8.23)


3
ตัดให้ฉันสองสามวินาที :)
rosuav

1
ขอบคุณมาก. ไม่เคยแม้แต่จะจินตนาการว่าการเรียงลำดับจะมีตัวเลือกเช่นนั้น
Mandragor

FWIW -Vสนับสนุนโดยค่าเริ่มต้นsortใน OpenBSD แต่ไม่ใช่ใน NetBSD
Kusalananda

FreeBSD ก็เห็นได้ชัดเช่นกันว่าหน้า man page นั้นมีตัวอย่างเอาต์พุตและดูเหมือนกับ 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

ขอบคุณสำหรับแรงบันดาลใจทั้งหมด - ฉันขอเสนอคำตอบของฉันเองได้: โปรแกรมเรียงลำดับสามารถหลอกให้ทำสิ่งที่ต้องการได้ ในที่สุดมันเป็นเรื่องเกี่ยวกับการเพิ่มหมายเลขที่สี่ให้กับการกำหนดเวอร์ชัน 3 หลักจัดเรียงแล้วลบออกอีกครั้ง ใช้งานได้ดีที่สุดจนถึงปัจจุบัน 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.