What's an effective way to filter access.log to return list of unique IP addresses and the number of successful requests (code 200) by each client?
apache, awk, bash, scripting
Solution
With awk :
awk '$(NF -1) == 200 {arr[$1]++}END{for (a in arr) print a, arr[a]}' access.log
Decomposing it a bit :
- `$(NF -1)` : `awk` by default split current line on spaces (or tabs and such), and `NF` is the numbers of columns, so `NF -1` is the second column one from the right and we test if it's value is 200
- if it's 200, then we increment the associative array `arr` with the IP address as key (`$1` : first column)
- @the end, we print each successful lines
Problem
I'm looking for a way to take an access.log formatted as shown below ``` 127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gig HTTP/1.0" 404 201 127.0.0.1 - frank [10/Oct/2000:13:56:40 -0700] "GET /apache_pb.gif HTTP/1.0" 200 1406 127.0.0.1 - frank [10/Oct/2000:13:57:45 -0700] "GET /apache_pb.gif HTTP/1.0" 200 5325 127.0.0.1 - frank [10/Oct/2000:13:58:16 -0700] "GET /apache_pb.gif HTTP/1.0" 200 35292 127.0.0.3 - jerry [10/Oct/2000:13:59:12 -0700] "GET /apache_pb.gif HTTP/1.0" 200 863 ``` and write a script that returns a result formatted like this: ``` 127.0.0.1 3 127.0.0.3 1 ``` The rules for the script are simple, it should count the number of times each unique IP address logs a successful access request (code 200). I'm totally open to doing this outside of bash. I just thought it might be easier to start there with grep, sort and uniq. The main issue I've had was that the output uniq -c has is in the wrong format. uniq has been listing output like so: ``` 3 127.0.0.1 1 127.0.0.3 ``` I can't have that, unfortunately. Any help at all is very much appreciated. Thanks!