Print the 3 most frequent IPs in an access log
Problem statement
A web server is under unusual load and you suspect a few clients. Print the 3 client IPs (field 1) with the most requests, with their counts, highest first. If two IPs have the same count, the one that sorts first as text wins. Output must be the same on every run.
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: Run the command on `access.log`.
Output: 4 10.0.0.5
3 192.168.1.20
2 10.0.0.7
Explanation: 10.0.0.7 and 172.16.0.3 both have 2 requests; the tie-break key picks 10.0.0.7.
Hints
Approach
awk '{print $1}' extracts the client IP. sort | uniq -c counts requests per IP. sort -k1,1nr -k2,2 sorts by the count (field 1) numerically in reverse, and for equal counts falls back to the IP (field 2) in normal text order, so the result is deterministic. head -n 3 stops after three lines. On large logs this is still fast, because the expensive step, sort, spills to disk instead of running out of memory.
awk '{print $1}' access.log | sort | uniq -c | sort -k1,1nr -k2,2 | head -n 3Follow-up questions
- Only count requests that returned a 4xx or 5xx status.
- How would you block the top IP with iptables or a WAF rule, and why is that risky behind a load balancer?
Frequently asked questions
-k1 alone means 'from field 1 to the end of the line', so the key would include the IP too. -k1,1 limits the key to exactly field 1. Get into the habit of always writing both the start and end field.