Bash and Linux

Count unique HTTP status codes

easysort, uniq, wc and pipes

Problem statement

Error rates look high on a web server. Using the access log, count how many requests returned each HTTP status code (field 9), most frequent first. Then report how many distinct status codes appeared.

access.log

TEXT
10.0.0.5 - - [20/Sep/2026:10:00:01 +0000] "GET / HTTP/1.1" 200 5120
192.168.1.20 - - [20/Sep/2026:10:00:02 +0000] "GET /login HTTP/1.1" 200 1834
10.0.0.5 - - [20/Sep/2026:10:00:03 +0000] "GET /api/users HTTP/1.1" 200 842
10.0.0.7 - - [20/Sep/2026:10:00:04 +0000] "GET /old-page HTTP/1.1" 301 0
192.168.1.20 - - [20/Sep/2026:10:00:05 +0000] "GET /wp-admin HTTP/1.1" 404 153
172.16.0.3 - - [20/Sep/2026:10:00:06 +0000] "GET /api/orders HTTP/1.1" 500 64
10.0.0.5 - - [20/Sep/2026:10:00:07 +0000] "GET /favicon.ico HTTP/1.1" 404 153
192.168.1.20 - - [20/Sep/2026:10:00:08 +0000] "GET /docs HTTP/1.1" 301 0
10.0.0.7 - - [20/Sep/2026:10:00:09 +0000] "GET /api/users HTTP/1.1" 200 842
172.16.0.3 - - [20/Sep/2026:10:00:10 +0000] "GET /robots.txt HTTP/1.1" 404 153
10.0.0.5 - - [20/Sep/2026:10:00:11 +0000] "GET /index.html HTTP/1.1" 200 5120

Examples

Example 1

Input: awk '{print $9}' access.log | sort | uniq -c | sort -rn

Output: 5 200 3 404 2 301 1 500

Explanation: GNU uniq -c right-aligns the count in a 7-character column.

Example 2

Input: awk '{print $9}' access.log | sort -u | wc -l

Output: 4

Explanation: Number of distinct status codes.

Hints

Approach

Optimal

awk '{print $9}' pulls out the status code from each line. sort groups identical codes next to each other, which uniq -c needs, since it only collapses adjacent duplicates. uniq -c then prints each distinct code once, prefixed by how many times it appeared. The final sort -rn sorts those lines numerically (-n) in reverse (-r), so the most common code is on top. For the distinct count, sort -u removes duplicates and wc -l counts what is left.

Bash
awk '{print $9}' access.log | sort | uniq -c | sort -rn

Follow-up questions

  • Print the percentage of requests that were 5xx.
  • How would you do the whole thing in a single awk command?

Frequently asked questions

The input was not sorted. uniq compares each line only with the one right before it, so 200 404 200 gives three groups. Always sort | uniq -c, or do the counting in awk with an array if you want to avoid the sort.