Sort Linux Text Reliably with sort: Keys, Numbers and Locale
You will turn an unsorted text file into a verified result, including the cases that catch people out: numeric values, selected fields, duplicate lines and locale-dependent order. The examples use GNU coreutils sort 9.4, installed from Ubuntu's coreutils package on the reference system. Allow about 10 minutes for a first pass. You need a shell and read access to the input file; none of the normal examples require sudo.
The route
Jump straight to the step you need, or tick off Done means at the end.
- 1. Check the installed command and make a working copy
- 2. Sort ordinary lines, then check the locale
- 3. Use numeric ordering when the key is a number
- 4. Sort by a field with a bounded key
- 5. Make ties predictable and remove duplicates intentionally
- 6. Write output without destroying the input
- 7. Diagnose the usual mistakes
1. Check the installed command and make a working copy
Confirm which implementation will run before building a script around it:
$ command -v sort
$ sort --version | head -n 1
The expected version line on the reference system is sort (GNU coreutils) 9.4. The command reads files named on the command line and writes the sorted result to standard output. With no file, or with -, it reads standard input.
For a safe first test, create a small input in a scratch directory. This changes only the file you explicitly create:
$ mkdir -p /tmp/sort-example
$ printf '%s\n' '10 apples' '2 pears' '1 oranges' > /tmp/sort-example/items.txt
$ cat /tmp/sort-example/items.txt
10 apples
2 pears
1 oranges
Checkpoint: you have a readable input file and know which sort implementation is in use.
2. Sort ordinary lines, then check the locale
With no ordering option, sort compares the whole line. Send the result to a new file or inspect it on screen:
$ sort /tmp/sort-example/items.txt
1 oranges
10 apples
2 pears
That is lexicographic order, so 10 comes before 2. The environment's locale affects comparisons. If a script needs stable byte-oriented ordering across machines, set LC_ALL=C for that command:
$ LC_ALL=C sort /tmp/sort-example/items.txt
1 oranges
10 apples
2 pears
Do not assume that a human-language locale and C produce the same order for accented or non-ASCII text. Choose deliberately, and record the choice in scripts. A locale is not an output decoration: it changes the comparison.
3. Use numeric ordering when the key is a number
Use -n for a string numerical comparison. Since the number is the first field in this example, the whole line can be used as the key:
$ sort -n /tmp/sort-example/items.txt
1 oranges
2 pears
10 apples
-g is a different general numerical sort, intended for values such as scientific notation and special floating-point values. -h understands human-readable suffixes such as K and G. Use the narrowest option that matches the data, and do not use -n merely because a line contains digits somewhere.
For version-like text, use -V rather than a numeric sort:
$ printf '%s\n' v1.10 v1.2 v1.9 | sort -V
v1.2
v1.9
v1.10
Checkpoint: the displayed order now matches the meaning of the values, not just their character sequence.
4. Sort by a field with a bounded key
Key definitions use one-based field numbers. Fields are separated by transitions between non-blank and blank characters unless you provide -t. For comma-separated data, make the separator explicit and bound the key at both ends:
$ printf '%s\n' 'Ada,42' 'Grace,7' 'Linus,19' > /tmp/sort-example/people.csv
$ sort -t, -k2,2n /tmp/sort-example/people.csv
Grace,7
Linus,19
Ada,42
-k2,2n means field 2 through field 2, using numeric ordering for that key. The second 2 matters: an unbounded -k2n can include later fields in the comparison. For whitespace-separated input, the equivalent pattern is commonly -k2,2n without -t.
Use a per-key suffix when a record needs more than one comparison. This sorts by department alphabetically and then by the second field numerically:
$ printf '%s\n' 'ops 20' 'dev 3' 'dev 12' 'ops 4' > /tmp/sort-example/teams.txt
$ sort -k1,1 -k2,2n /tmp/sort-example/teams.txt
dev 3
dev 12
ops 4
ops 20
5. Make ties predictable and remove duplicates intentionally
GNU sort applies a last-resort whole-line comparison when selected keys compare equal. Add -s when the original order of equal keys must be preserved. Add -u when you want one line from each equal run:
$ printf '%s\n' b a a c b | sort -u
a
b
c
Without a key, -u removes identical complete lines. With a key, equality is based on the selected comparison, so two different records can collapse if their keys compare equal. Read the command as a data decision, not just a formatting shortcut.
To check a file without producing a sorted replacement, use -c:
$ sort -c /tmp/sort-example/people.csv
A successful check is silent and returns status zero. Use -C when you need a quiet status-only check even if the file is out of order. These checks use the same ordering options you pass, so check a keyed file with the same -t and -k settings used to create it.
6. Write output without destroying the input
Prefer redirection to a new destination while testing:
$ sort -t, -k2,2n /tmp/sort-example/people.csv > /tmp/sort-example/people.sorted.csv
$ sort -c -t, -k2,2n /tmp/sort-example/people.sorted.csv
$ diff -u /tmp/sort-example/people.csv /tmp/sort-example/people.sorted.csv
Shell redirection with > truncates an existing destination before sort starts. That is irreversible if the only copy is there. Keep the original until the new file has passed its check and any downstream consumer has accepted it.
The -o FILE option writes to a named output file and GNU sort can use the same path as an input. Treat in-place replacement as a deliberate state change: save a backup first, then verify the result. If a command is interrupted or the result is wrong, restore the backup with cp; do not delete the original as part of an untested one-liner. Elevated privileges are only appropriate when the chosen input or output path is genuinely protected, and sudo does not make bad sorting rules safe.
7. Diagnose the usual mistakes
- If numbers appear in character order, add the correct numeric suffix to the key, such as
-k2,2n. - If a field sort produces surprising results, specify
-tfor a single-character separator and bound the key with-kSTART,END. - If two machines disagree, compare
localeoutput and try an explicitLC_ALL=Cwhen byte order is the requirement. - If an input path contains unusual characters or starts with a hyphen, use an explicit path such as
./-records.txtor terminate options with--where appropriate. - For many input names,
--files0-from=FILEreads NUL-terminated names. This avoids newline-based name ambiguity, but the name list itself must be produced safely.
Sorting is normally unprivileged and does not change the input. The main risks are choosing the wrong comparison and overwriting the only useful copy. Keep the comparison options beside the command in a script, and retain a verification step.
Done means
- The installed GNU
sortversion and locale assumptions are known. - The key and ordering mode match the data: plain, numeric, human-readable, version or another documented comparison.
- Field keys have an explicit separator where needed and a bounded end field.
- Duplicates and ties are handled intentionally with
-uor-s. - The result was checked with
sort -cusing the same key options. - The original input remains available until the sorted output is accepted.