Getting Started with sort and uniq: Sorting Data and Removing Duplicates
What you'll be able to do
- Sort lines alphabetically, numerically, and in reverse with `sort`
- Explain why `uniq` needs `sort` in front of it
- Build a frequency ranking with `sort | uniq -c | sort -rn`
Prerequisites (read these first)
What You'll Learn
- How to sort lines with
sort(alphabetical, numeric, reverse) - How to remove duplicate lines with
uniq— and why it implicitly requiressort - How to write the classic frequency ranking pipeline
sort | uniq -c | sort -rn - Why beginners get stuck on "uniq doesn't remove duplicates" and "numbers come out in a weird order"
Words used here (sorted out first)
- Line: one line inside a file. Everything between one line break and the next.
- Field: one part of a line after you split it on spaces. "Column" means the same thing. This article says "column".
- Alphabetical order: comparing text one character at a time, from the left. "Dictionary order" and "string order" mean the same thing.
- Numeric order: comparing the lines as numbers. The result differs from alphabetical order. That difference is the first trap.
- Duplicate: two or more lines whose contents are exactly the same.
- Pipe: the
|symbol. It hands the output of one command straight to the next one. - Redirection: the
>symbol. It writes output to a file instead of the screen. It does not behave like "save over the file" in an editor — section 7-3 explains why.
Quick Summary
- Want to sort? →
sort - Want to sort and dedupe? →
sort -u - Want to count occurrences? →
sort | uniq -c | sort -rn
Environment
- OS: Ubuntu / typical Linux
- GNU coreutils
sort/uniq(BSD versions on macOS differ in some option details) - Sort order depends on your locale, the language and region setting. The output here is what you get under
LC_ALL=C, which compares characters strictly by their character codes
1. What Does "Sorting Lines" Mean?
Conclusion:
sortprints sorted output without touching the file.
sort is for. sort filename reads the file line by line and prints the sorted result.Let's prepare a sample file:
$ cat fruits.txt
banana apple cherry apple banana date
1-1. Basic: Alphabetical Order
$ sort fruits.txt
apple apple banana banana cherry date
Key points
sortdefaults to alphabetical (dictionary) order- Uppercase and lowercase are treated as different characters. Which one comes first depends on your locale
- The original file is not modified.
sortonly prints the sorted result
1-2. Reverse (Descending) Order: -r
$ sort -r fruits.txt
date cherry banana banana apple apple
-r stands for reverse.
2. The Numeric Sort Trap
Conclusion:
sortcompares as strings by default; add-nfor numbers.
$ cat scores.txt
100 3 25 9 1000
$ sort scores.txt
100 1000 25 3 9
100 comes before 25, and 3 and 9 are at the end. Is this a bug?sort does string comparison, one character at a time, from the left.1 is smaller than 2 or 3. That is why 100 and 1000 move to the front.-n. That one option fixes it.2-1. Numeric Sort: -n
$ sort -n scores.txt
3 9 25 100 1000
-n stands for numeric.
Beginner pitfall
- Forgetting
-nwhen sorting sizes or counts produces the wrong order - Rule of thumb: if the column holds numbers, add
-n
2-2. Numbers in Descending Order
$ sort -nr scores.txt
1000 100 25 9 3
-n and -r combine freely. This combination appears in nearly every ranking task.
3. Sort + Deduplicate in One Shot: sort -u
Conclusion:
sort -usorts and removes duplicates in one command.
$ sort -u fruits.txt
apple banana cherry date
apple and banana appear only once each.-u stands for unique. It removes duplicate lines from the sorted result.In real work, "give me the unique values" is one of the most common requests. sort -u is the shortcut.
4. uniq: The Deduplication Specialist
Conclusion:
uniqonly drops adjacent duplicates, so runsortfirst.
4-1. Lina Gets Stuck: uniq Alone Removes Nothing
$ uniq fruits.txt
banana apple cherry apple banana date
apple and banana are still duplicated. Did the command do nothing?uniq only removes duplicates that sit next to each other.apple is on line 2 and line 4. cherry sits between them, so uniq sees two separate groups.sort first. Once sort puts identical lines next to each other, uniq can collapse them properly.Why sort has to come first
uniq reads one line at a time and compares it only with the line right before it. It never remembers the whole file.
So identical lines that sit far apart both survive. sort gathers identical lines together. That is what lets uniq do its job.
4-2. The sort | uniq Pattern
$ sort fruits.txt | uniq
apple banana cherry date
Rule of thumb
uniqalways goes aftersort- Use
uniqalone only when you already know the input is sorted - If "sort and dedupe" is all you want,
sort -uis shorter
4-3. Counting Occurrences: uniq -c
$ sort fruits.txt | uniq -c
2 apple
2 banana
1 cherry
1 date
-c stands for count. Each line gets its occurrence count in front. This is extremely useful for aggregation.
4-4. Duplicates Only / Singletons Only
# Show only lines that appear more than once $ sort fruits.txt | uniq -d
apple banana
# Show only lines that appear exactly once $ sort fruits.txt | uniq -u
cherry date
| Option | Meaning | Use case |
|---|---|---|
-c |
Prepend count | Aggregation |
-d |
Duplicates only | Find duplicated items |
-u |
Singletons only | Extract values seen exactly 1x |
-i |
Case-insensitive compare | Merge case variants |
Both sort and uniq have a -u option, and they mean different things. sort -u collapses duplicates into one line. uniq -u keeps only the lines that appear exactly once. Do not mix them up.
5. The Real-World Workhorse: Frequency Ranking
Conclusion:
sort | uniq -c | sort -rnis the frequency ranking idiom.
sort | uniq -c | sort -rn is the standard idiom.Sample log:
$ cat access.log
192.168.1.10 192.168.1.20 192.168.1.10 192.168.1.30 192.168.1.10 192.168.1.20
Frequency ranking:
$ sort access.log | uniq -c | sort -rn
3 192.168.1.10
2 192.168.1.20
1 192.168.1.30
Pipeline breakdown
| Stage | Command | What it does |
|---|---|---|
| 1 | sort |
Brings identical lines next to each other |
| 2 | uniq -c |
Collapses adjacent duplicates with a count |
| 3 | sort -rn |
Sorts by count (numeric) in descending order |
Drop the first sort and stage 2 miscounts. It would treat identical lines that sit far apart as separate groups.
Stage 3 sorts again because the thing being sorted has changed. Up to stage 2 the lines were ordered by their text. Stage 3 reorders them by the count that stage 2 just added.
5-1. Top N Only
$ sort access.log | uniq -c | sort -rn | head -n 3
head -n 3 keeps the top 3 entries. Combining with head is the everyday pattern.
6. Advanced: Sort by a Specific Column with -k
Conclusion:
-k2picks the sort column; add-nfor numeric fields.
For CSV or whitespace-separated data, use -k. It chooses which column to sort by.
$ cat sales.txt
apple 120 banana 80 cherry 200 date 50
# Sort by the 2nd column (numeric) in descending order $ sort -k2 -nr sales.txt
cherry 200 apple 120 banana 80 date 50
-k2selects the second column as the sort key- Use
-nwhenever that column holds numbers - To change the delimiter, use
-t,(comma-separated) or-t:
7. Common Beginner Pitfalls
Conclusion: Duplicates linger without
sort; numbers need-n.
7-1. uniq Didn't Remove the Duplicates
Cause: forgot to sort first.
# BAD: non-adjacent duplicates are not removed $ uniq fruits.txt # GOOD $ sort fruits.txt | uniq $ sort -u fruits.txt
7-2. Numbers Came Out in a Weird Order
Cause: forgot -n. sort is doing string comparison.
$ sort -n scores.txt # Sort as numbers
7-3. The Original File Wasn't Modified
sort only prints to the screen. It never modifies the input file. To save the sorted result, redirect it yourself.
$ sort fruits.txt > fruits-sorted.txt
Never do this
# BAD: this empties the file $ sort fruits.txt > fruits.txt
> empties the destination file before the command runs. So sort reads an empty file. This is not how "save over the file" works in a GUI editor.
To write back to the same file safely, sort into a second file and swap it in. Or use sort -o.
# GOOD: -o writes only after reading is finished $ sort -o fruits.txt fruits.txt
The virtual terminalAn interactive program that reads the commands you type and runs them. on this site is for learning. Nothing here can damage the files on your own computer, so try it freely.
7-4. Upper/Lowercase Are Treated as Different
$ cat names.txt
Alice bob Alice BOB
$ LC_ALL=C sort -u names.txt
Alice BOB bob
LC_ALL=C is there to make your order match this article. Without it, some locales put bob before BOB.
To ignore case, add -f (fold case).
$ LC_ALL=C sort -uf names.txt
Alice bob
8. Mini Exercises
Conclusion: Three drills: dedupe, count, and rank in descending order.
Exercise 1: Print the unique words from this file.
$ cat << 'EOF' > words.txt apple banana apple cherry banana EOF
Show hint 1 (direction)
One option does "sort" and "remove duplicates" in a single step. Look back at section 3.
Show hint 2 (command name)
The command is sort. One of its options does the sorting and the deduplication in a single step — look for it with sort --help.
Show answer
$ sort -u words.txt
apple banana cherry
Exercise 2: Count how many times each word appears.
Show hint 1 (direction)
Before you can count, identical words have to sit next to each other. So this needs a two-stage pipe.
Show hint 2 (command name)
The commands are sort and uniq. uniq has an option that counts occurrences.
Show answer
$ sort words.txt | uniq -c
2 apple
2 banana
1 cherry
Exercise 3: Sort the counts in descending order and show only the top 2.
Show hint 1 (direction)
The count column holds numbers. Reorder by that number, largest first. Then take only the first two lines.
Show hint 2 (command name)
The commands are sort and head. sort has one option for treating values as numbers and another for reversing the order.
Show answer
$ sort words.txt | uniq -c | sort -rn | head -n 2
2 banana
2 apple
apple and banana both appear twice. When the counts tie, the whole line decides the order. -r reverses that comparison too, so banana lands first.
9. Copy-Paste Templates
Conclusion: Keep the sort, dedupe, and ranking patterns close at hand.
Patterns to keep handy
# Sort alphabetically sort file.txt # Sort and deduplicate sort -u file.txt # Sort numerically (ascending / descending) sort -n file.txt sort -nr file.txt # Count occurrences per line sort file.txt | uniq -c # Frequency ranking (most frequent first) sort file.txt | uniq -c | sort -rn # Top 10 frequency ranking sort file.txt | uniq -c | sort -rn | head -n 10 # Sort by 2nd column, descending numeric sort -k2 -nr file.txt # Case-insensitive unique values sort -uf file.txt # Sort in place safely (avoids the > self-truncation bug) sort -o file.txt file.txt
10. Review
uniq only looks at neighbouring lines, so sort has to gather them first.-n. Without it they get compared as text. I have that too.sort file > file. It wipes the contents.Today's 3-Line Summary
uniqonly drops duplicates that sit next to each other, so runsortfirst to gather them- Add
-nwhen sorting numbers. Without it they are compared as text - The frequency ranking is the three-stage pipeline
sort | uniq -c | sort -rn