1@c GNU Version-sort ordering documentation 2 3@c Copyright (C) 2019--2023 Free Software Foundation, Inc. 4 5@c Permission is granted to copy, distribute and/or modify this document 6@c under the terms of the GNU Free Documentation License, Version 1.3 or 7@c any later version published by the Free Software Foundation; with no 8@c Invariant Sections, no Front-Cover Texts, and no Back-Cover 9@c Texts. A copy of the license is included in the ``GNU Free 10@c Documentation License'' file as part of this distribution. 11 12@c Written by Assaf Gordon 13 14@node Version sort ordering 15@chapter Version sort ordering 16 17 18 19@node Version sort overview 20@section Version sort overview 21 22@dfn{Version sort} puts items such as file names and lines of 23text in an order that feels natural to people, when the text 24contains a mixture of letters and digits. 25 26Lexicographic sorting usually does not produce the order that one expects 27because comparisons are made on a character-by-character basis. 28 29Compare the sorting of the following items: 30 31@example 32Lexicographic sort: Version Sort: 33 34a1 a1 35a120 a2 36a13 a13 37a2 a120 38@end example 39 40Version sort functionality in GNU Coreutils is available in the @samp{ls -v}, 41@samp{ls --sort=version}, @samp{sort -V}, and 42@samp{sort --version-sort} commands. 43 44 45 46@node Using version sort in GNU Coreutils 47@subsection Using version sort in GNU Coreutils 48 49Two GNU Coreutils programs use version sort: @command{ls} and @command{sort}. 50 51To list files in version sort order, use @command{ls} 52with the @option{-v} or @option{--sort=version} option: 53 54@example 55default sort: version sort: 56 57$ ls -1 $ ls -1 -v 58a1 a1 59a100 a1.4 60a1.13 a1.13 61a1.4 a1.40 62a1.40 a2 63a2 a100 64@end example 65 66To sort text files in version sort order, use @command{sort} with 67the @option{-V} or @option{--version-sort} option: 68 69@example 70$ cat input 71b3 72b11 73b1 74b20 75 76 77lexicographic order: version sort order: 78 79$ sort input $ sort -V input 80b1 b1 81b11 b3 82b20 b11 83b3 b20 84@end example 85 86To sort a specific field in a file, use @option{-k/--key} with 87@samp{V} type sorting, which is often combined with @samp{b} to 88ignore leading blanks in the field: 89 90@example 91$ cat input2 92100 b3 apples 932000 b11 oranges 943000 b1 potatoes 954000 b20 bananas 96$ sort -k 2bV,2 input2 973000 b1 potatoes 98100 b3 apples 992000 b11 oranges 1004000 b20 bananas 101@end example 102 103@node Version sort and natural sort 104@subsection Version sort and natural sort 105 106In GNU Coreutils, the name @dfn{version sort} was chosen because it is based 107on Debian GNU/Linux's algorithm of sorting packages' versions. 108 109Its goal is to answer questions like 110``Which package is newer, @file{firefox-60.7.2} or @file{firefox-60.12.3}?'' 111 112In Coreutils this algorithm was slightly modified to work on more 113general input such as textual strings and file names 114(see @ref{Differences from Debian version sort}). 115 116In other contexts, such as other programs and other programming 117languages, a similar sorting functionality is called 118@uref{https://en.wikipedia.org/wiki/Natural_sort_order,natural sort}. 119 120 121@node Variations in version sort order 122@subsection Variations in version sort order 123 124Currently there is no standard for version sort. 125 126That is: there is no one correct way or universally agreed-upon way to 127order items. Each program and each programming language can decide its 128own ordering algorithm and call it ``version sort'', ``natural sort'', 129or other names. 130 131See @ref{Other version/natural sort implementations} for many examples of 132differing sorting possibilities, each with its own rules and variations. 133 134If you find a bug in the Coreutils implementation of version-sort, please 135report it. @xref{Reporting version sort bugs}. 136 137 138@node Version sort implementation 139@section Version sort implementation 140 141GNU Coreutils version sort is based on the ``upstream version'' 142part of 143@uref{https://www.debian.org/doc/debian-policy/ch-controlfields.html#version, 144Debian's versioning scheme}. 145 146This section describes the GNU Coreutils sort ordering rules. 147 148The next section (@ref{Differences from Debian version 149sort}) describes some differences between GNU Coreutils 150and Debian version sort. 151 152 153@node Version-sort ordering rules 154@subsection Version-sort ordering rules 155 156The version sort ordering rules are: 157 158@enumerate 159@item 160The strings are compared from left to right. 161 162@item 163First the initial part of each string consisting entirely of non-digit 164bytes is determined. 165 166@enumerate A 167@item 168These two parts (either of which may be empty) are compared lexically. 169If a difference is found it is returned. 170 171@item 172The lexical comparison is a lexicographic comparison of byte strings, 173except that: 174 175@enumerate a 176@item 177ASCII letters sort before other bytes. 178@item 179A tilde sorts before anything, even an empty string. 180@end enumerate 181@end enumerate 182 183@item 184Then the initial part of the remainder of each string that contains 185all the leading digits is determined. The numerical values represented by 186these two parts are compared, and any difference found is returned as 187the result of the comparison. 188 189@enumerate A 190@item 191For these purposes an empty string (which can only occur at the end of 192one or both version strings being compared) counts as zero. 193 194@item 195Because the numerical value is used, non-identical strings can compare 196equal. For example, @samp{123} compares equal to @samp{00123}, and 197the empty string compares equal to @samp{0}. 198@end enumerate 199 200@item 201These two steps (comparing and removing initial non-digit strings and 202initial digit strings) are repeated until a difference is found or 203both strings are exhausted. 204@end enumerate 205 206Consider the version-sort comparison of two file names: 207@file{foo07.7z} and @file{foo7a.7z}. The two strings will be broken 208down to the following parts, and the parts compared respectively from 209each string: 210 211@example 212foo @r{vs} foo @r{(rule 2, non-digits)} 21307 @r{vs} 7 @r{(rule 3, digits)} 214. @r{vs} a. @r{(rule 2)} 2157 @r{vs} 7 @r{(rule 3)} 216z @r{vs} z @r{(rule 2)} 217@end example 218 219Comparison flow based on above algorithm: 220 221@enumerate 222@item 223The first parts (@samp{foo}) are identical. 224 225@item 226The second parts (@samp{07} and @samp{7}) are compared numerically, 227and compare equal. 228 229@item 230The third parts (@samp{.} vs @samp{a.}) are compared 231lexically by ASCII value (rule 2.B). 232 233@item 234The first byte of the first string (@samp{.}) is compared 235to the first byte of the second string (@samp{a}). 236 237@item 238Rule 2.B.a says letters sorts before non-letters. 239Hence, @samp{a} comes before @samp{.}. 240 241@item 242The returned result is that @file{foo7a.7z} comes before @file{foo07.7z}. 243@end enumerate 244 245Result when using sort: 246 247@example 248$ cat input3 249foo07.7z 250foo7a.7z 251$ sort -V input3 252foo7a.7z 253foo07.7z 254@end example 255 256See @ref{Differences from Debian version sort} for 257additional rules that extend the Debian algorithm in Coreutils. 258 259 260@node Version sort is not the same as numeric sort 261@subsection Version sort is not the same as numeric sort 262 263Consider the following text file: 264 265@example 266$ cat input4 2678.10 2688.5 2698.1 2708.01 2718.010 2728.100 2738.49 274 275Numerical Sort: Version Sort: 276 277$ sort -n input4 $ sort -V input4 2788.01 8.01 2798.010 8.1 2808.1 8.5 2818.10 8.010 2828.100 8.10 2838.49 8.49 2848.5 8.100 285@end example 286 287Numeric sort (@samp{sort -n}) treats the entire string as a single numeric 288value, and compares it to other values. For example, @samp{8.1}, @samp{8.10} and 289@samp{8.100} are numerically equivalent, and are ordered together. Similarly, 290@samp{8.49} is numerically less than @samp{8.5}, and appears before first. 291 292Version sort (@samp{sort -V}) first breaks down the string into digit and 293non-digit parts, and only then compares each part (see annotated 294example in @ref{Version-sort ordering rules}). 295 296Comparing the string @samp{8.1} to @samp{8.01}, first the 297@samp{8}s are compared (and are identical), then the 298dots (@samp{.}) are compared and are identical, and lastly the 299remaining digits are compared numerically (@samp{1} and @samp{01}) -- 300which are numerically equal. Hence, @samp{8.01} and @samp{8.1} 301are grouped together. 302 303Similarly, comparing @samp{8.5} to @samp{8.49} -- the @samp{8} 304and @samp{.} parts are identical, then the numeric values @samp{5} and 305@samp{49} are compared. The resulting @samp{5} appears before @samp{49}. 306 307This sorting order (where @samp{8.5} comes before @samp{8.49}) is common when 308assigning versions to computer programs (while perhaps not intuitive 309or ``natural'' for people). 310 311@node Version sort punctuation 312@subsection Version sort punctuation 313 314Punctuation is sorted by ASCII order (rule 2.B). 315 316@example 317$ touch 1.0.5_src.tar.gz 1.0_src.tar.gz 318$ ls -v -1 3191.0.5_src.tar.gz 3201.0_src.tar.gz 321@end example 322 323Why is @file{1.0.5_src.tar.gz} listed before @file{1.0_src.tar.gz}? 324 325Based on the version-sort ordering rules, the strings are broken down 326into the following parts: 327 328@example 329 1 @r{vs} 1 @r{(rule 3, all digits)} 330 . @r{vs} . @r{(rule 2, all non-digits)} 331 0 @r{vs} 0 @r{(rule 3)} 332 . @r{vs} _src.tar.gz @r{(rule 2)} 333 5 @r{vs} empty string @r{(no more bytes in the file name)} 334_src.tar.gz @r{vs} empty string 335@end example 336 337The fourth parts (@samp{.} and @samp{_src.tar.gz}) are compared 338lexically by ASCII order. The @samp{.} (ASCII value 46) is 339less than @samp{_} (ASCII value 95) -- and should be listed before it. 340 341Hence, @file{1.0.5_src.tar.gz} is listed first. 342 343If a different byte appears instead of the underscore (for 344example, percent sign @samp{%} ASCII value 37, which is less 345than dot's ASCII value of 46), that file will be listed first: 346 347@example 348$ touch 1.0.5_src.tar.gz 1.0%zzzzz.gz 3491.0%zzzzz.gz 3501.0.5_src.tar.gz 351@end example 352 353The same reasoning applies to the following example, as @samp{.} with 354ASCII value 46 is less than @samp{/} with ASCII value 47: 355 356@example 357$ cat input5 3583.0/ 3593.0.5 360$ sort -V input5 3613.0.5 3623.0/ 363@end example 364 365 366@node Punctuation vs letters 367@subsection Punctuation vs letters 368 369Rule 2.B.a says letters sort before non-letters 370(after breaking down a string to digit and non-digit parts). 371 372@example 373$ cat input6 374a% 375az 376$ sort -V input6 377az 378a% 379@end example 380 381The input strings consist entirely of non-digits, and based on the 382above algorithm have only one part, all non-digits 383(@samp{a%} vs @samp{az}). 384 385Each part is then compared lexically, 386byte-by-byte; @samp{a} compares identically in both 387strings. 388 389Rule 2.B.a says a letter like @samp{z} sorts before 390a non-letter like @samp{%} -- hence @samp{az} appears first (despite 391@samp{z} having ASCII value of 122, much larger than @samp{%} 392with ASCII value 37). 393 394@node The tilde @samp{~} 395@subsection The tilde @samp{~} 396 397Rule 2.B.b says the tilde @samp{~} (ASCII 126) sorts 398before other bytes, and before an empty string. 399 400@example 401$ cat input7 4021 4031% 4041.2 4051~ 406~ 407$ sort -V input7 408~ 4091~ 4101 4111% 4121.2 413@end example 414 415The sorting algorithm starts by breaking down the string into 416non-digit (rule 2) and digit parts (rule 3). 417 418In the above input file, only the last line in the input file starts 419with a non-digit (@samp{~}). This is the first part. All other lines 420in the input file start with a digit -- their first non-digit part is 421empty. 422 423Based on rule 2.B.b, tilde @samp{~} sorts before other bytes 424and before the empty string -- hence it comes before all other strings, 425and is listed first in the sorted output. 426 427The remaining lines (@samp{1}, @samp{1%}, @samp{1.2}, @samp{1~}) 428follow similar logic: The digit part is extracted (1 for all strings) 429and compares equal. The following extracted parts for the remaining 430input lines are: empty part, @samp{%}, @samp{.}, @samp{~}. 431 432Tilde sorts before all others, hence the line @samp{1~} appears next. 433 434The remaining lines (@samp{1}, @samp{1%}, @samp{1.2}) are sorted based 435on previously explained rules. 436 437@node Version sort ignores locale 438@subsection Version sort ignores locale 439 440In version sort, Unicode characters are compared byte-by-byte according 441to their binary representation, ignoring their Unicode value or the 442current locale. 443 444Most commonly, Unicode characters are encoded as UTF-8 bytes; for 445example, GREEK SMALL LETTER ALPHA (U+03B1, @samp{α}) is encoded as the 446UTF-8 sequence @samp{0xCE 0xB1}). The encoding is compared 447byte-by-byte, e.g., first @samp{0xCE} (decimal value 206) then 448@samp{0xB1} (decimal value 177). 449 450@example 451$ touch aa az "a%" "aα" 452$ ls -1 -v 453aa 454az 455a% 456aα 457@end example 458 459Ignoring the first letter (@samp{a}) which is identical in all 460strings, the compared values are: 461 462@samp{a} and @samp{z} are letters, and sort before 463all other non-digits. 464 465Then, percent sign @samp{%} (ASCII value 37) is compared to the 466first byte of the UTF-8 sequence of @samp{α}, which is 0xCE or 206). The 467value 37 is smaller, hence @samp{a%} is listed before @samp{aα}. 468 469@node Differences from Debian version sort 470@section Differences from Debian version sort 471 472GNU Coreutils version sort differs slightly from the 473official Debian algorithm, in order to accommodate more general usage 474and file name listing. 475 476 477@node Hyphen-minus and colon 478@subsection Hyphen-minus @samp{-} and colon @samp{:} 479 480In Debian's version string syntax the version consists of three parts: 481@example 482[epoch:]upstream_version[-debian_revision] 483@end example 484The @samp{epoch} and @samp{debian_revision} parts are optional. 485 486Example of such version strings: 487 488@example 48960.7.2esr-1~deb9u1 49052.9.0esr-1~deb9u1 4911:2.3.4-1+b2 492327-2 4931:1.0.13-3 4942:1.19.2-1+deb9u5 495@end example 496 497If the @samp{debian_revision part} is not present, 498hyphens @samp{-} are not allowed. 499If epoch is not present, colons @samp{:} are not allowed. 500 501If these parts are present, hyphen and/or colons can appear only once 502in valid Debian version strings. 503 504In GNU Coreutils, such restrictions are not reasonable (a file name can 505have many hyphens, a line of text can have many colons). 506 507As a result, in GNU Coreutils hyphens and colons are treated exactly 508like all other punctuation, i.e., they are sorted after 509letters. @xref{Version sort punctuation}. 510 511In Debian, these characters are treated differently than in Coreutils: 512a version string with hyphen will sort before similar strings without 513hyphens. 514 515Compare: 516 517@example 518$ touch 1ab-cd 1abb 519$ ls -v -1 5201abb 5211ab-cd 522$ if dpkg --compare-versions 1abb lt 1ab-cd 523> then echo sorted 524> else echo out of order 525> fi 526out of order 527@end example 528 529For further details, see @ref{Comparing two strings using Debian's 530algorithm} and @uref{https://bugs.gnu.org/35939,GNU Bug 35939}. 531 532@node Special priority in GNU Coreutils version sort 533@subsection Special priority in GNU Coreutils version sort 534 535In GNU Coreutils version sort, the following items have 536special priority and sort before all other strings (listed in order): 537 538@enumerate 539@item The empty string 540 541@item The string @samp{.} (a single dot, ASCII 46) 542 543@item The string @samp{..} (two dots) 544 545@item Strings starting with dot (@samp{.}) sort before 546strings starting with any other byte. 547@end enumerate 548 549Example: 550 551@example 552$ printf '%s\n' a "" b "." c ".." ".d20" ".d3" | sort -V 553. 554.. 555.d3 556.d20 557a 558b 559c 560@end example 561 562These priorities make perfect sense for @samp{ls -v}: The special 563files dot @samp{.} and dot-dot @samp{..} will be listed 564first, followed by any hidden files (files starting with a dot), 565followed by non-hidden files. 566 567For @samp{sort -V} these priorities might seem arbitrary. However, 568because the sorting code is shared between the @command{ls} and @command{sort} 569program, the ordering rules are the same. 570 571@node Special handling of file extensions 572@subsection Special handling of file extensions 573 574GNU Coreutils version sort implements specialized handling 575of strings that look like file names with extensions. 576This enables slightly more natural ordering of file 577names. 578 579The following additional rules apply when comparing two strings where 580both begin with non-@samp{.}. They also apply when comparing two 581strings where both begin with @samp{.} but neither is @samp{.} or @samp{..}. 582 583@enumerate 584@item 585A suffix (i.e., a file extension) is defined as: a dot, followed by an 586ASCII letter or tilde, followed by zero or more ASCII letters, digits, 587or tildes; all repeated zero or more times, and ending at string end. 588This is equivalent to matching the extended regular expression 589@code{(\.[A-Za-z~][A-Za-z0-9~]*)*$} in the C locale. 590The longest such match is used, except that a suffix is not 591allowed to match an entire nonempty string. 592 593@item 594The suffixes are temporarily removed, and the strings are compared 595without them, using version sort (see @ref{Version-sort ordering 596rules}) without special priority (see @ref{Special priority in GNU 597Coreutils version sort}). 598 599@item 600If the suffix-less strings do not compare equal, this comparison 601result is used and the suffixes are effectively ignored. 602 603@item 604If the suffix-less strings compare equal, the suffixes are restored 605and the entire strings are compared using version sort. 606@end enumerate 607 608Examples for rule 1: 609 610@itemize 611@item 612@samp{hello-8.txt}: the suffix is @samp{.txt} 613 614@item 615@samp{hello-8.2.txt}: the suffix is @samp{.txt} 616(@samp{.2} is not included because the dot is not followed by a letter) 617 618@item 619@samp{hello-8.0.12.tar.gz}: the suffix is @samp{.tar.gz} (@samp{.0.12} 620is not included) 621 622@item 623@samp{hello-8.2}: no suffix (suffix is an empty string) 624 625@item 626@samp{hello.foobar65}: the suffix is @samp{.foobar65} 627 628@item 629@samp{gcc-c++-10.8.12-0.7rc2.fc9.tar.bz2}: the suffix is 630@samp{.fc9.tar.bz2} (@samp{.7rc2} is not included as it begins with a digit) 631 632@item 633@samp{.autom4te.cfg}: the suffix is the entire string. 634@end itemize 635 636Examples for rule 2: 637 638@itemize 639@item 640Comparing @samp{hello-8.txt} to @samp{hello-8.2.12.txt}, the 641@samp{.txt} suffix is temporarily removed from both strings. 642 643@item 644Comparing @samp{foo-10.3.tar.gz} to @samp{foo-10.tar.xz}, the suffixes 645@samp{.tar.gz} and @samp{.tar.xz} are temporarily removed from the 646strings. 647@end itemize 648 649Example for rule 3: 650 651@itemize 652@item 653Comparing @samp{hello.foobar65} to @samp{hello.foobar4}, the suffixes 654(@samp{.foobar65} and @samp{.foobar4}) are temporarily removed. The 655remaining strings are identical (@samp{hello}). The suffixes are then 656restored, and the entire strings are compared (@samp{hello.foobar4} comes 657first). 658@end itemize 659 660Examples for rule 4: 661 662@itemize 663@item 664When comparing the strings @samp{hello-8.2.txt} and @samp{hello-8.10.txt}, the 665suffixes (@samp{.txt}) are temporarily removed. The remaining strings 666(@samp{hello-8.2} and @samp{hello-8.10}) are compared as previously described 667(@samp{hello-8.2} comes first). 668@slanted{(In this case the suffix removal algorithm 669does not have a noticeable effect on the resulting order.)} 670@end itemize 671 672@b{How does the suffix-removal algorithm effect ordering results?} 673 674Consider the comparison of hello-8.txt and hello-8.2.txt. 675 676Without the suffix-removal algorithm, the strings will be broken down 677to the following parts: 678 679@example 680hello- @r{vs} hello- @r{(rule 2, all non-digits)} 6818 @r{vs} 8 @r{(rule 3, all digits)} 682.txt @r{vs} . @r{(rule 2)} 683empty @r{vs} 2 684empty @r{vs} .txt 685@end example 686 687The comparison of the third parts (@samp{.} vs 688@samp{.txt}) will determine that the shorter string comes first -- 689resulting in @file{hello-8.2.txt} appearing first. 690 691Indeed this is the order in which Debian's @command{dpkg} compares the strings. 692 693A more natural result is that @file{hello-8.txt} should come before 694@file{hello-8.2.txt}, and this is where the suffix-removal comes into play: 695 696The suffixes (@samp{.txt}) are removed, and the remaining strings are 697broken down into the following parts: 698 699@example 700hello- @r{vs} hello- @r{(rule 2, all non-digits)} 7018 @r{vs} 8 @r{(rule 3, all digits)} 702empty @r{vs} . @r{(rule 2)} 703empty @r{vs} 2 704@end example 705 706As empty strings sort before non-empty strings, the result is @samp{hello-8} 707being first. 708 709A real-world example would be listing files such as: 710@file{gcc_10.fc9.tar.gz} 711and @file{gcc_10.8.12.7rc2.fc9.tar.bz2}: Debian's algorithm would list 712@file{gcc_10.8.12.7rc2.fc9.tar.bz2} first, while @samp{ls -v} will list 713@file{gcc_10.fc9.tar.gz} first. 714 715These priorities make sense for @samp{ls -v}: 716Versioned files will be listed in a more natural order. 717 718For @samp{sort -V} these priorities might seem arbitrary. However, 719because the sorting code is shared between the @command{ls} and @command{sort} 720program, the ordering rules are the same. 721 722 723@node Comparing two strings using Debian's algorithm 724@subsection Comparing two strings using Debian's algorithm 725 726The Debian program @command{dpkg} (available on all Debian and Ubuntu 727installations) can compare two strings using the @option{--compare-versions} 728option. 729 730To use it, create a helper shell function (simply copy & paste the 731following snippet to your shell command-prompt): 732 733@example 734compver() @{ 735 if dpkg --compare-versions "$1" lt "$2" 736 then printf '%s\n' "$1" "$2" 737 else printf '%s\n' "$2" "$1" 738 fi 739@} 740@end example 741 742Then compare two strings by calling @command{compver}: 743 744@example 745$ compver 8.49 8.5 7468.5 7478.49 748@end example 749 750Note that @command{dpkg} will warn if the strings have invalid syntax: 751 752@example 753$ compver "foo07.7z" "foo7a.7z" 754dpkg: warning: version 'foo07.7z' has bad syntax: 755 version number does not start with digit 756dpkg: warning: version 'foo7a.7z' has bad syntax: 757 version number does not start with digit 758foo7a.7z 759foo07.7z 760$ compver "3.0/" "3.0.5" 761dpkg: warning: version '3.0/' has bad syntax: 762 invalid character in version number 7633.0.5 7643.0/ 765@end example 766 767To illustrate the different handling of hyphens between Debian and 768Coreutils algorithms (see 769@ref{Hyphen-minus and colon}): 770 771@example 772$ compver abb ab-cd 2>/dev/null $ printf 'abb\nab-cd\n' | sort -V 773ab-cd abb 774abb ab-cd 775@end example 776 777To illustrate the different handling of file extension: (see @ref{Special 778handling of file extensions}): 779 780@example 781$ compver hello-8.txt hello-8.2.txt 2>/dev/null 782hello-8.2.txt 783hello-8.txt 784$ printf '%s\n' hello-8.txt hello-8.2.txt | sort -V 785hello-8.txt 786hello-8.2.txt 787@end example 788 789 790@node Advanced version sort topics 791@section Advanced Topics 792 793 794@node Reporting version sort bugs 795@subsection Reporting version sort bugs 796 797If you suspect a bug in GNU Coreutils version sort (i.e., in the 798output of @samp{ls -v} or @samp{sort -V}), please first check the following: 799 800@enumerate 801@item 802Is the result consistent with Debian's own ordering (using @command{dpkg}, see 803@ref{Comparing two strings using Debian's algorithm})? If it is, then this 804is not a bug -- please do not report it. 805 806@item 807If the result differs from Debian's, is it explained by one of the 808sections in @ref{Differences from Debian version sort}? If it is, 809then this is not a bug -- please do not report it. 810 811@item 812If you have a question about specific ordering which is not explained 813here, please write to @email{coreutils@@gnu.org}, and provide a 814concise example that will help us diagnose the issue. 815 816@item 817If you still suspect a bug which is not explained by the above, please 818write to @email{bug-coreutils@@gnu.org} with a concrete example of the 819suspected incorrect output, with details on why you think it is 820incorrect. 821 822@end enumerate 823 824@node Other version/natural sort implementations 825@subsection Other version/natural sort implementations 826 827As previously mentioned, there are multiple variations on 828version/natural sort, each with its own rules. Some examples are: 829 830@itemize 831 832@item 833Natural Sorting variants in 834@uref{https://rosettacode.org/wiki/Natural_sorting,Rosetta Code}. 835 836@item 837Python's @uref{https://pypi.org/project/natsort/,natsort package} 838(includes detailed description of their sorting rules: 839@uref{https://natsort.readthedocs.io/en/master/howitworks.html, 840natsort -- how it works}). 841 842@item 843Ruby's @uref{https://github.com/github/version_sorter,version_sorter}. 844 845@item 846Perl has multiple packages for natural and version sorts 847(each likely with its own rules and nuances): 848@uref{https://metacpan.org/pod/Sort::Naturally,Sort::Naturally}, 849@uref{https://metacpan.org/pod/Sort::Versions,Sort::Versions}, 850@uref{https://metacpan.org/pod/CPAN::Version,CPAN::Version}. 851 852@item 853PHP has a built-in function 854@uref{https://www.php.net/manual/en/function.natsort.php,natsort}. 855 856@item 857NodeJS's @uref{https://www.npmjs.com/package/natural-sort,natural-sort package}. 858 859@item 860In zsh, the 861@uref{http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Qualifiers, 862glob modifier} @samp{*(n)} will expand to files in natural sort order. 863 864@item 865When writing C programs, the GNU libc library (@samp{glibc}) 866provides the 867@uref{https://man7.org/linux/man-pages/man3/strverscmp.3.html, 868strverscmp(3)} function to compare two strings, and 869@uref{https://man7.org/linux/man-pages/man3/versionsort.3.html,versionsort(3)} 870function to compare two directory entries (despite the names, they are 871not identical to GNU Coreutils version sort ordering). 872 873@item 874Using Debian's sorting algorithm in: 875 876@itemize 877@item 878python: @uref{https://stackoverflow.com/a/4957741, 879Stack Overflow Example #4957741}. 880 881@item 882NodeJS: @uref{https://www.npmjs.com/package/deb-version-compare, 883deb-version-compare}. 884@end itemize 885 886@end itemize 887 888 889@node Related source code 890@subsection Related source code 891 892@itemize 893 894@item 895Debian's code which splits a version string into 896@code{epoch/upstream_version/debian_revision} parts: 897@uref{https://git.dpkg.org/cgit/dpkg/dpkg.git/tree/lib/dpkg/parsehelp.c#n191, 898parsehelp.c:parseversion()}. 899 900@item 901Debian's code which performs the @code{upstream_version} comparison: 902@uref{https://git.dpkg.org/cgit/dpkg/dpkg.git/tree/lib/dpkg/version.c#n140, 903version.c}. 904 905@item 906Gnulib code (used by GNU Coreutils) which performs the version comparison: 907@uref{https://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/filevercmp.c, 908filevercmp.c}. 909@end itemize 910