Skip to content

bug: sort -n doesn't extract leading numeric prefix from strings #833

@chaliy

Description

@chaliy

Problem

sort -n correctly sorts pure numeric input but fails to extract leading numeric prefixes from strings. In real coreutils sort -n, lines like 0003-msg.md are sorted by their leading number 3, with non-numeric suffixes compared lexically as tiebreakers.

Additionally, sort -t DELIM -k FIELD (field-based sorting) does not sort correctly.

Both patterns are used by wedow/harness for:

  • Ordering message sequence files: ls -1 msgs/ | sort -n | tail -1
  • Ordering hook scripts: printf '%s\n' "${order[@]}" | sort -t/ -k1,1

Reproduction

# Pure numbers — works:
printf '3\n1\n2\n' | sort -n
# Output: 1 2 3 ✓

# Strings with numeric prefix — broken:
printf '0003-msg.md\n0001-msg.md\n0002-msg.md\n' | sort -n
# Expected: 0001-msg.md  0002-msg.md  0003-msg.md
# Actual:   0003-msg.md  0001-msg.md  0002-msg.md  (unsorted)

# Field-based sort — broken:
printf 'assemble/20-tools\nassemble/10-init\nassemble/30-end\n' | sort -t/ -k1,1
# Expected: assemble/10-init  assemble/20-tools  assemble/30-end
# Actual:   assemble/20-tools  assemble/10-init  assemble/30-end  (unsorted)

Test cases

sort -n with numeric prefix strings

printf '0003-msg.md\n0001-msg.md\n0002-msg.md\n' | sort -n
# Expected stdout:
#   0001-msg.md
#   0002-msg.md
#   0003-msg.md

sort -n with mixed prefix lengths

printf '10-exec\n20-tools\n5-first\n' | sort -n
# Expected stdout:
#   5-first
#   10-exec
#   20-tools

sort -n treats non-numeric lines as 0

printf 'zzz\n2-second\naaa\n1-first\n' | sort -n
# Expected stdout:
#   aaa
#   zzz
#   1-first
#   2-second
# (non-numeric lines have value 0 and are compared lexically among themselves)

sort -t with -k (field-based)

printf 'assemble/20-tools\nassemble/10-init\nassemble/30-end\n' | sort -t/ -k2,2
# Expected stdout:
#   assemble/10-init
#   assemble/20-tools
#   assemble/30-end

sort -t/ -k1,1 (harness hook ordering)

printf 'z/20-tools\na/10-init\nm/30-end\n' | sort -t/ -k1,1
# Expected stdout:
#   a/10-init
#   m/30-end
#   z/20-tools

sort -n -r (reverse numeric)

printf '1\n3\n2\n' | sort -n -r
# Expected stdout:
#   3
#   2
#   1

sort -n with zero-padded numbers

printf '003\n010\n001\n' | sort -n
# Expected stdout:
#   001
#   003
#   010

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions