uniq
Overview
uniq reports or filters adjacent duplicate lines. It does not search the whole file for duplicates unless identical lines are already next to each other — which is why the standard pattern is sort | uniq. GNU uniq can count runs, show only duplicates, or skip comparison of leading fields/characters.
Syntax
uniq [OPTIONS] [INPUT [OUTPUT]]
command | uniq [OPTIONS]Common Options
| Option | Description |
|---|---|
-c |
Prefix each line with occurrence count |
-d |
Only print lines that are duplicated |
-D |
Print all duplicate lines (GNU; every copy in a run) |
-u |
Only print lines that are unique (appear once) |
-i |
Case-insensitive compare |
-f N |
Skip first N fields when comparing |
-s N |
Skip first N characters when comparing |
-w N |
Compare at most N characters |
-z |
NUL-terminated lines (GNU) |
Examples with Explanations
Remove adjacent duplicates
printf 'a\na\nb\na\n' | uniq
# → a / b / a (the second 'a' group is separate)Without sorting, non-adjacent duplicates remain.
The usual “unique lines in file” pattern
sort names.txt | uniq
sort -u names.txt # often faster one-process equivalentCount occurrences
sort access-hosts.txt | uniq -c
sort access-hosts.txt | uniq -c | sort -nr | headuniq -c counts runs; sorting first groups equal lines so the count is global.
Top IPs from a log (field extract → sort → uniq -c → sort)
awk '{print $1}' /var/log/nginx/access.log \
| sort \
| uniq -c \
| sort -nr \
| head -n 20Only lines that appear more than once
sort ids.txt | uniq -dOnly lines that appear exactly once
sort ids.txt | uniq -uCase-insensitive uniqueness
printf 'Foo\nfoo\nBAR\n' | sort -f | uniq -iSort with matching case rules (-f) so case variants become adjacent.
Ignore leading fields when comparing
# two columns: timestamp id — unique by id only among adjacent
sort -k2,2 events.txt | uniq -f 1-f 1 skips field 1 (the timestamp) during comparison; whitespace field rules match sort’s default.
Compare only a prefix of each line
uniq -w 8 hashes.txtUseful when a fixed-width key leads the line.
Show every line that is part of a duplicate group
sort data.txt | uniq -DNUL-separated path lists
find . -type f -print0 | sort -z | uniq -z | xargs -0 …Rare but correct for exotic pipelines that stay NUL-safe end-to-end.
Count total unique lines (quick)
sort file.txt | uniq | wc -l
# or
sort -u file.txt | wc -lUnderstanding Output
Default: one line per adjacent run of identical lines. With -c, output looks like:
12 10.0.0.5
7 10.0.0.8
1 10.0.0.9
Counts are right-aligned in a fixed width (GNU). Leading spaces are normal — strip with awk '{print $1}' when you need the number alone.
Notes & Pitfalls
uniqwithoutsortonly collapses neighbors. This is the #1 misconception.sort -uandsort | uniqare often equivalent for whole-line uniqueness; prefer one clear form in scripts.- Locale can affect whether lines compare equal; use
LC_ALL=Cfor byte-wise behavior in tooling. uniq -c | sort -nsorts by the whole line as text unless you usesort -nrand account for leading spaces —sort -k1,1nris clearer on counted output.- Blank lines are real lines; consecutive empties collapse under
uniq. - For multisets and complex keys,
awkassociative arrays ordatamashmay be clearer thanuniq -fgymnastics.
Additional Resources
man uniq- GNU coreutils info:
info uniq