# Count, Sort, Remove Duplicates: wc, sort and uniq

wc counts lines, words and characters, sort puts lines in order, as text or with -n as numbers, and uniq merges repeated lines that sit next to each other, so sort | uniq -c | sort -rn ranks how often each line appears.

Apprentice · Unix · Linux · Updated November 10, 2026

## After this lesson you can

- Count lines, words and characters with wc, using -l, -w and -c
- Sort lines with sort, -n and -r, and rank repeated lines with sort, uniq -c and sort -rn

## Key takeaways

- wc -l counts lines, -w words and -c characters. Given no file name, wc counts what comes through a pipe.
- sort puts lines in alphabetical order. -n sorts them as numbers, and -r reverses the order.
- uniq merges a repeated line only when it sits right after its twin, so sort first. uniq -c writes how many times each line appeared.
- sort | uniq -c | sort -rn counts how often each line appears, most often first. It's worth knowing by heart.

Bea wants to open a stall at a farmers' market, and she wants it in the city her online orders come from most. With 520 orders, a tally on paper would take an afternoon, and one slip spoils it. A spreadsheet can do it, after some clicking through menus. In the terminal it's one line, and it's a line you'll use again and again: a data analyst counting survey answers, a web developer finding a website's most visited pages, an IT tech finding which laptop breaks most often.

The examples use the bakery folder from *Pipes: |* (its setup lines make it). Go into it with `cd ~/terminal-practice/bakery`.

## A column on its own

The question is about one column, the city. This line saves it in a file of its own, `cities.txt`, one city a line. Take its first half on trust for now: `cut -d, -f5` takes the fifth column of every line, and `tail -n +2` (read "tail from line 2") starts at the second line, which leaves out the header. *Columns and Characters: cut and tr*, next, explains both.

```bash
cut -d, -f5 orders.csv | tail -n +2 > cities.txt
head -n 4 cities.txt
```

```text
Portland
Bend
Corvallis
Portland
```

## wc: how many?

`wc` (*word count*) counts. With `-l` (for *lines*), the one you'll use most, it counts lines:

```bash
wc -l orders.csv cities.txt
```

```text
  521 orders.csv
  520 cities.txt
 1041 total
```

`orders.csv` has 521 lines: 520 orders and the header. Given two files, `wc` adds a total. Without an option, it prints three counts, lines, words and characters, before the name:

```bash
wc orders.csv
```

```text
  521  1383 41043 orders.csv
```

`-w` (*words*) and `-c` (*characters*) ask for one of the other two. Strictly, `-c` counts bytes, which is the same as characters for plain English text. Give `wc` no file name, and it counts what comes through a pipe. This is how many orders came from Medford:

```bash
grep Medford orders.csv | wc -l
```

```text
27
```

On a Mac, `wc` puts more spaces in front of its numbers; the numbers are the same.

## sort: put lines in order

`sort` prints lines in alphabetical order, so the same cities end up together:

```bash
sort cities.txt | head -n 3
```

```text
Bend
Bend
Bend
```

Numbers are a trap. `sort` compares lines character by character, the way a dictionary orders words, so `128.50` comes before `9.75`, because 1 comes before 9. Here are three order totals, one a line, made with `printf` from *Writing to Files: echo, > and >>*:

```bash
printf '%s\n' 9.75 32.00 128.50 | sort
```

```text
128.50
32.00
9.75
```

`-n` (for *numeric*) sorts by the value of the number instead. `-r` (for *reverse*) turns any order upside down, so `-rn` puts the biggest number first.

```bash
printf '%s\n' 9.75 32.00 128.50 | sort -n
```

```text
9.75
32.00
128.50
```

## uniq: merge the repeats

`uniq` (*unique*) prints each line once, but it merges a repeat only when it comes right after its twin. In `cities.txt` the cities are mixed up, so few repeats are neighbors:

```bash
uniq cities.txt | wc -l
```

```text
375
```

375 lines, from a file of six cities. Sort first, and every Portland lands next to every other Portland:

```bash
sort cities.txt | uniq
```

```text
Bend
Corvallis
Eugene
Medford
Portland
Salem
```

`sort -u` (for *unique*) does both in one command: `sort -u cities.txt` prints the same six lines.

## The pattern: sort | uniq -c | sort -rn

`uniq -c` (for *count*) writes in front of each line how many times it appeared:

```bash
sort cities.txt | uniq -c
```

```text
     89 Bend
     23 Corvallis
     73 Eugene
     27 Medford
    212 Portland
     96 Salem
```

That's the answer, in alphabetical order. Sort it by the counts, as numbers, biggest first, and the top line answers Bea's question:

```bash
sort cities.txt | uniq -c | sort -rn
```

```text
    212 Portland
     96 Salem
     89 Bend
     73 Eugene
     27 Medford
     23 Corvallis
```

Portland, by a long way. Read the pattern aloud: sort, so repeats are neighbors; count each one; sort by the counts, biggest first. It works on any column. Here it ranks the bestsellers, straight from `orders.csv`, with `head -n 3` keeping the top three:

```bash
cut -d, -f6 orders.csv | tail -n +2 | sort | uniq -c | sort -rn | head -n 3
```

```text
    175 sourdough loaf
    100 croissant
     80 blueberry muffin
```

![Two short lists of cities side by side. On the left, Portland, Bend, Portland goes straight into uniq -c and comes out as 1 Portland, 1 Bend, 1 Portland, labeled "Not sorted: the two Portlands aren't neighbors". On the right, the same list goes through sort first, becoming Bend, Portland, Portland, then uniq -c gives 1 Bend, 2 Portland, labeled "Sorted: every Portland is counted together".](https://fsdtrainingmedia.blob.core.windows.net/public/images/2026/11/3b49017452c84a70bbb6d172e17301e0.webp)

The slip to watch for is leaving out the first `sort`. `uniq -c` then counts only runs of neighbors, and Portland shows up dozens of times with small counts. (On a Mac, `uniq -c` puts fewer spaces before each count; the counts are the same.)

## Check yourself

2 questions to try on the lesson page.

## So what

`sort | uniq -c | sort -rn` turns any list into a ranking: cities, bestsellers, a website's visitors, the errors in a log. It's one of the most useful lines in this course.

## Key terms

- [wc](https://www.ask-codey.com/glossary/wc)
- [sort and uniq](https://www.ask-codey.com/glossary/sort-and-uniq)

## Cheat sheets

- [Count, Sort, Remove Duplicates: wc, sort and uniq](https://www.ask-codey.com/cheat-sheets/bash-count-sort-unique-cheat-sheet)

## Related

- [Pipes: |](https://www.ask-codey.com/lessons/bash-pipes)
- [Columns and Characters: cut and tr](https://www.ask-codey.com/lessons/bash-cut-and-tr)

Source: https://www.ask-codey.com/lessons/bash-count-sort-unique
