sort
Overview
sort orders lines of text (or selected fields) and can merge pre-sorted files. It is a core building block for log analytics, unique counts (sort | uniq -c), and deterministic output in scripts. GNU sort (Ubuntu default) supports huge files via temporary disk, multiple keys, numeric/version/human-size modes, and stable sort.
Syntax
sort [OPTIONS] [FILE...]
command | sort [OPTIONS]With no files (or -), reads stdin. Multiple files are concatenated then sorted unless -m merges already-sorted inputs.
Common Options
| Option | Description |
|---|---|
-n |
Numeric sort |
-h |
Human numeric (2K, 3M, 1G) |
-V |
Version sort (v2.10 after v2.9) |
-r |
Reverse |
-u |
Unique (drop duplicate lines after sort) |
-f |
Fold case (ignore case) |
-b |
Ignore leading blanks |
-k POS[,POS] |
Sort by key/field (see below) |
-t CHAR |
Field separator |
-s |
Stable sort (preserve order of equal keys) |
-R |
Random shuffle (hash-based) |
-o file |
Write output to file (safe for in-place with care) |
-m |
Merge already-sorted files |
-c / -C |
Check whether sorted (-C quiet) |
-z |
NUL-terminated lines (with find -print0 pipelines) |
--parallel=N |
Parallel sort threads (GNU) |
-S size |
Memory buffer size (GNU) |
Key syntax (-k)
Fields are 1-based. Examples: - -k2,2 — only field 2
- -k2 — field 2 through end of line
- -k2n — field 2 as number
- -k1,1 -k2,2n — first by field 1, then numeric field 2
Default field separator is non-blank to blank transitions (whitespace runs).
Examples with Explanations
Lexicographic sort
sort names.txt
sort -r names.txtNumeric sort
sort -n scores.txt
printf '10\n2\n1\n' | sort -nWithout -n, 10 sorts before 2 as text.
Human-readable sizes
du -h /var/* 2>/dev/null | sort -h
du -h /var/* 2>/dev/null | sort -hr | headVersion numbers
printf 'v1.9\nv1.10\nv2.0\n' | sort -VSort by a column (whitespace)
# passwd-like: sort by UID (field 3) numerically
sort -t: -k3,3n /etc/passwdCSV-ish second column (simple cases)
sort -t, -k2,2 file.csvEmbedded commas/quotes need a real CSV tool (mlr, python); sort is field-dumb.
Unique lines
sort -u access-hosts.txt
# equivalent pipeline often written as:
sort access-hosts.txt | uniqFrequency report (sort | uniq -c | sort)
awk '{print $1}' access.log | sort | uniq -c | sort -nr | headClassic “top talkers” pattern: count then re-sort by count.
Check if already sorted
sort -c names.txt && echo sorted
sort -C names.txt # silent; use exit statusSafe “sort in place”
sort -o names.txt names.txtGNU sort handles -o same-file correctly; sort file > file truncates first and destroys data.
Merge pre-sorted shards
sort -m part-a.txt part-b.txt part-c.txt > all-sorted.txtMuch faster than re-sorting the concatenation when inputs are already ordered.
Stable sort by key, preserve secondary order
sort -s -k1,1 events.logNUL-safe with find
find . -type f -print0 | sort -z | xargs -0 ls -lRandomize lines
sort -R items.txt | head -n 5For cryptographic shuffles use shuf instead of relying on sort -R alone.
Understanding Output
Output is the full lines in sorted order. With -u, only the first of equal lines (per current key/order rules) remains. Exit status 0 on success; sort -c returns non-zero if out of order.
Locale (LC_COLLATE / LANG) affects byte vs dictionary order. For scripts that need byte-wise sort:
LC_ALL=C sort fileNotes & Pitfalls
- Locale surprises:
en_US.UTF-8vsCcan reorder punctuation and case. PinLC_ALL=Cfor deterministic machine output. - Numeric sort of non-numeric prefixes:
sort -nparses a leading number; garbage may sort as zero. -k2vs-k2,2is a frequent bug — open-ended keys include the rest of the line.- Large sorts use
/tmp(or$TMPDIR); disk-full mid-sort fails — free space or set-S/TMPDIRon big data hosts. sort -uuniqueness respects the sort keys/options, not always the whole line if keys are restricted — know what you keyed.- Prefer
shuffor sampling random lines; prefermlr/csvkitfor real CSV.
Additional Resources
man sort- GNU coreutils info:
info sort