Count unique HTTP status codes
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
10.0.0.5 - - [20/Sep/2026:10:00:01 +0000] "GET / HTTP/1.1" 200 5120192.168.1.20 - - [20/Sep/2026:10:00:02 +0000] "GET /login HTTP/1.1" 200 183410.0.0.5 - - [20/Sep/2026:10:00:03 +0000] "GET /api/users HTTP/1.1" 200 84210.0.0.7 - - [20/Sep/2026:10:00:04 +0000] "GET /old-page HTTP/1.1" 301 0192.168.1.20 - - [20/Sep/2026:10:00:05 +0000] "GET /wp-admin HTTP/1.1" 404 153172.16.0.3 - - [20/Sep/2026:10:00:06 +0000] "GET /api/orders HTTP/1.1" 500 6410.0.0.5 - - [20/Sep/2026:10:00:07 +0000] "GET /favicon.ico HTTP/1.1" 404 153192.168.1.20 - - [20/Sep/2026:10:00:08 +0000] "GET /docs HTTP/1.1" 301 010.0.0.7 - - [20/Sep/2026:10:00:09 +0000] "GET /api/users HTTP/1.1" 200 842172.16.0.3 - - [20/Sep/2026:10:00:10 +0000] "GET /robots.txt HTTP/1.1" 404 15310.0.0.5 - - [20/Sep/2026:10:00:11 +0000] "GET /index.html HTTP/1.1" 200 5120Examples
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.
awk '{print $9}' access.log | sort | uniq -c | sort -rnFollow-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.