Linux Basics: Order Numbered Filenames with GNU Version Sort
Numbered report names often sort as 1, 10, 2 under ordinary text ordering. GNU version sorting compares digit runs numerically within text, making numbered filenames easier to scan.
Prepare a scratch directory
Tested on Linux with GNU coreutils 9.7, GNU findutils 4.10.0, and GNU Bash 5.2.37. You need Bash, a text editor, and the utilities used below. The script creates its own temporary fixture directory and removes only that directory on exit.
Keep the same terminal open. Stop if setup fails, before saving the source:
start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1Run the example
Save this as demonstrate-gnu-sort-version-order.sh:
#!/usr/bin/env bash
set -euo pipefail
export LC_ALL=C
fixture_dir="$(mktemp -d)"
trap 'rm -rf -- "$fixture_dir"' EXIT
cd -- "$fixture_dir"
printf '%s\n' report-10.txt report-2.txt report-1.txt > names.txt
printf 'Lexical order:\n'
sort names.txt
printf 'Version order:\n'
sort -V names.txt
printf '%s\n' 'worker 2.10' 'api 2.9' 'web 2.1' > releases.txt
printf 'Order by the second field:\n'
sort -k2,2V releases.txt
test "$(sort -V names.txt | head -n 1)" = report-1.txtRun it:
bash demonstrate-gnu-sort-version-order.shObserved output:
Lexical order:
report-1.txt
report-10.txt
report-2.txt
Version order:
report-1.txt
report-2.txt
report-10.txt
Order by the second field:
web 2.1
api 2.9
worker 2.10Read the result
-V applies GNU version comparison to each complete line. The final command restricts its version key to field two with -k2,2V; the service name is not part of that key. Each command writes a new ordering to standard output and leaves its input file unchanged. Setting LC_ALL=C also makes the ordinary lexical comparison predictable.
Apply it carefully
Version sort is a documented GNU ordering, not a Semantic Versioning validator or a package manager dependency resolver. Do not assume arbitrary prerelease labels, leading zeros, punctuation, or suffixes follow the rules of another version scheme. Use that ecosystem’s parser when upgrade decisions depend on its exact ordering. These fixtures contain one filename per line; use NUL-delimited records and compatible options throughout when actual filenames may contain newlines.
The GNU reference documents these options and their behavior.
Clean up
Remove the saved script, return to the starting directory, and remove the empty practice directory:
rm -- demonstrate-gnu-sort-version-order.sh
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dirIf the directory is not empty, inspect what remains rather than deleting unknown files.
Acknowledgements
This post was created with assistance from AI.