Sorting seems like such a basic operation until you actually need to sort a CSV file by the third column numerically, or sort a list of filenames by modification date, and suddenly the default sort command output looks nothing like what you expected. I’ve hit this wall enough times that I finally sat down and learned sort and its related flags properly, and it’s paid off constantly since.
This guide covers sorting file contents with the sort command, sorting file listings with ls, and some related tools like sort -u for deduplication and combining sort with other commands in pipelines.
The Basic sort Command
The sort command reads lines from a file (or standard input) and outputs them in sorted order.
sort names.txt
By default, this sorts lines alphabetically (technically, based on locale collation rules).
Sorting in Reverse Order
sort -r names.txt
-r— reverses the sort order, so it goes from Z to A instead of A to Z.
Sorting Numerically
Here’s where a lot of people get tripped up. If you have a file like this:
10
2
33
4
Running plain sort on it gives:
10
2
33
4
That’s because default sort treats these as strings, comparing character by character rather than as numbers. To sort them correctly as numbers:
sort -n numbers.txt
Output:
2
4
10
33
-n— tellssortto interpret each line as a number for comparison purposes.
Sorting by a Specific Column
Suppose you have a file data.txt with space-separated columns:
Alice 25 Engineering
Bob 30 Marketing
Charlie 22 Sales
To sort by the second column (age), numerically:
sort -k2 -n data.txt
-k2— sort based on the second field (Bash counts fields starting from 1).-n— treat the values in that field as numbers.
Output:
Charlie 22 Sales
Alice 25 Engineering
Bob 30 Marketing
Sorting CSV Files by Column
If your data is comma-separated instead of space-separated, you need to tell sort what the field separator is:
sort -t',' -k3,3n data.csv
-t','— sets the delimiter to a comma.-k3,3n— sort using only field 3 (from field 3 to field 3), treated as a number.
Removing Duplicates While Sorting
sort -u names.txt
-u— unique, removes duplicate lines from the sorted output.
This is different from running sort and uniq separately, though the result is the same — sort -u does it in one pass, which is slightly more efficient.
Case-Insensitive Sorting
sort -f names.txt
-f— fold lowercase to uppercase for comparison purposes, effectively making the sort case-insensitive.
Sorting by Multiple Keys
You can sort by more than one column, using the second as a tiebreaker:
sort -k3,3 -k2,2n data.txt
This sorts primarily by field 3 alphabetically, and where values in field 3 are equal, it sorts by field 2 numerically as a secondary criterion.
Sorting Human-Readable Sizes
If you’re working with output from du -h or ls -lh that includes sizes like 1.5K, 20M, 3G, plain numeric sort won’t understand these suffixes correctly.
du -h * | sort -h
-h— human-numeric sort, understands suffixes like K, M, G, and sorts them in the correct real-world order.
Sorting Files by Name Using ls
While sort works on file contents, you’ll also often want to sort directory listings themselves.
Alphabetical (Default)
ls
By default, ls sorts alphabetically.
By Modification Time
ls -lt
-t— sort by modification time, newest first.
To reverse it (oldest first):
ls -ltr
By File Size
ls -lS
-S— sort by file size, largest first.
To reverse it (smallest first):
ls -lSr
Combining sort With Other Commands in a Pipeline
One of the most powerful things about sort is how naturally it slots into pipelines. Here’s an example that finds the five largest files in a directory:
du -ah . | sort -rh | head -n 5
Breaking this down:
du -ah .— lists disk usage for every file and directory recursively, in human-readable format.sort -rh— sorts that output by size, largest first (-rfor reverse,-hfor human-numeric).head -n 5— trims the output down to just the top 5 results.
Here’s another one, counting and sorting word frequency in a text file:
cat article.txt | tr ' ' '\n' | sort | uniq -c | sort -rn | head -n 10
How this works step by step:
tr ' ' '\n'— replaces every space with a newline, putting one word per line.sort— sorts words alphabetically so identical words end up adjacent to each other.uniq -c— counts consecutive duplicate lines (this only works correctly because the input is already sorted).sort -rn— sorts by count, numerically, in descending order.head -n 10— shows only the top 10 most frequent words.
This kind of pipeline is a classic example of Unix philosophy in action: small tools chained together to do something none of them could do alone.
Writing Sorted Output to a New File
sort names.txt -o sorted_names.txt
-o— output to a specified file instead of standard output. This is safer thansort names.txt > names.txt, which can actually truncate the input file before sort finishes reading it, corrupting your data.
Real-World Use Cases
Log analysis: Sorting log entries by timestamp to reconstruct the correct chronological order when logs from multiple sources have been merged.
Data cleanup: Sorting and deduplicating a list of email addresses or usernames before importing into a database.
Disk usage audits: Sorting du output to quickly identify what’s consuming the most storage on a server.
Report generation: Sorting CSV exports by a specific column (like revenue or date) before generating summary reports in scripts.
Automation Example: Cleaning and Sorting a Contact List
#!/bin/bash
INPUT="contacts_raw.txt"
OUTPUT="contacts_sorted.txt"
sort -u "$INPUT" -o "$OUTPUT"
echo "Sorted and deduplicated contact list saved to $OUTPUT"
echo "Original had $(wc -l < "$INPUT") lines, cleaned list has $(wc -l < "$OUTPUT") lines."
This script sorts and deduplicates a raw contact list in one step, then reports how many duplicate or redundant lines were removed — useful for a quick sanity check after cleaning data.
Best Practices
- Always use
-nwhen sorting numbers to avoid incorrect string-based comparisons. - Use
-oinstead of shell redirection when sorting a file back into itself. - Combine
sort -uinstead of piping touniqseparately when you don’t need the intermediate non-deduplicated sorted output. - Be explicit about field delimiters (
-t) when working with CSVs or other structured text, since default whitespace splitting can misinterpret your data. - Test sort behavior on a small sample before running it against large production files.
Security Considerations
- Be cautious sorting files with untrusted or unexpected encoding, as locale settings can affect sort order in subtle, sometimes exploitable ways in security-sensitive contexts (like sorting before deduplication of access control lists).
- Avoid sorting sensitive files (like ones containing credentials) into world-readable output locations.
Optimization Tips
- For very large files that don’t fit comfortably in memory,
sortautomatically uses temporary disk space and merge sorting, but you can tune this with--buffer-sizefor better performance on large datasets. - Use
LC_ALL=C sortfor faster, byte-based sorting when you don’t need locale-aware collation — this can meaningfully speed up sorting large text files.
Troubleshooting Common Issues
Numbers sorted incorrectly (10 before 2): You forgot the -n flag — default sort treats input as strings.
Sort seems to ignore a column: Double-check your field delimiter with -t, especially with CSVs, since default sort splits on whitespace.
Sort output looks scrambled with special characters: This can be a locale issue — try prefixing the command with LC_ALL=C to force simple byte-order sorting.
uniq isn’t removing duplicates: Remember that uniq only removes consecutive duplicate lines, so the input must be sorted first for it to work correctly.
Frequently Asked Questions
Does sort modify the original file? No, by default sort prints to standard output. Use -o or redirection to save changes, but never redirect directly back into the same file you’re reading from without -o.
Can I sort in place? Yes, using the -o flag with the same filename as input: sort -u file.txt -o file.txt is safe because sort reads the entire input before writing output.
How do I sort a file by the last column instead of a fixed column number? There’s no direct built-in support for “last field” since field count varies per line, but you can use awk to rearrange fields first, then pipe to sort.
Is sort case-sensitive by default? Yes, uppercase letters typically sort before lowercase in default locale settings. Use -f for case-insensitive sorting.
Common Mistakes to Avoid
- Forgetting
-nand assuming numeric sort happened automatically. - Redirecting sort output directly back into the same input file without
-o, risking data loss. - Ignoring locale settings when sort order looks unexpectedly different across systems.
- Assuming
sort -uandsort | uniqbehave identically in every edge case — they usually do, but-uis more efficient and preferred.
Summary
The sort command is deceptively powerful once you get past the default alphabetical behavior. Learning flags like -n for numeric sorting, -k for column-based sorting, -h for human-readable sizes, and -u for deduplication opens up a huge range of practical, everyday uses — from cleaning data files to building analysis pipelines. Combined with ls sorting options for file listings, you have everything you need to organize and analyze data directly from the terminal.
References
- GNU Coreutils Manual — sort: https://www.gnu.org/software/coreutils/manual/html_node/sort-invocation.html
- GNU Bash Manual: https://www.gnu.org/software/bash/manual/bash.html
