[SadServers] 解説 "Saskatoon": counting IPs.
"Saskatoon": counting IPs.
SadServersの問題の解説です。 URLは、https://sadservers.com/newserver/saskatoon#
SadServers って何? って人は、 SadServers解説 を見てください。
一言でいうと、LeetCode (コーディング問題集) の Linuxサーバ設定版のようなものです。
問題
Level: Easy
Description: There's a web server access log file at /home/admin/access.log. The file consists of one line per HTTP request, with the requester's IP address at the beginning of each line.
Find what's the IP address that has the most requests in this file (there's no tie; the IP is unique). Write the solution into a file /home/admin/highestip.txt. For example, if your solution is "1.2.3.4", you can do echo "1.2.3.4" > /home/admin/highestip.txt
Webサーバーのアクセスログファイルは、/home/admin/access.logにあります。このファイルは、HTTPリクエストごとに1行で構成されており、各行の先頭にリクエスト元のIPアドレスが記載されています。
このファイルの中で最も多くのリクエストを持つIPアドレスは何かを見つけなさい(同点はない。IPは一意である)。その解答をファイル /home/admin/highestip.txt に書き込んでください。たとえば、あなたの解決策が "1.2.3.4" であれば、次のようになります echo "1.2.3.4" > /home/admin/highestip.txt
Test: The SHA1 checksum of the IP address sha1sum /home/admin/highestip.txt is 6ef426c40652babc0d081d438b9f353709008e93 (just a way to verify the solution without giving it away.)
IPアドレスのSHA1チェックサム sha1sum /home/admin/highestip.txt は 6ef426c40652babc0d081d438b9f353709008e93 (あくまで解を明かさないための検証方法)です。
Time to Solve: 15 minutes.
OS: Debian 11
解き方
/home/admin/access.log を見ると、行頭にIPアドレスが記載されている、次のようなデータとなっています。
dmin@ip-172-31-27-155:/$ cat /home/admin/access.log
83.149.9.216 - - [17/May/2015:10:05:03 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-search.png HTTP/1.1" 200 203023 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
83.149.9.216 - - [17/May/2015:10:05:43 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-dashboard3.png HTTP/1.1" 200 171717 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
各行の先頭のIPアドレスだけを取り出すために cut
コマンドを使います。
-d ' '
でスペース区切りで分割し、 -f 1
で 1番目の区切り要素(先頭)を出力します。
admin@ip-172-31-27-155:/$ cat /home/admin/access.log | cut -d' ' -f 1
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
83.149.9.216
順番を並べ替えるために sort
コマンドを使います。
admin@ip-172-31-27-155:/$ cat /home/admin/access.log | cut -d' ' -f 1 | sort
1.22.35.226
1.22.35.226
1.22.35.226
1.22.35.226
1.22.35.226
1.22.35.226
100.2.4.116
100.2.4.116
100.2.4.116
連続するIPアドレスの数を数えるために、uniq -c
を使います。
行頭にカウント数が記されます。
admin@ip-172-31-27-155:/$ cat /home/admin/access.log | cut -d' ' -f 1 | sort | uniq -c
6 1.22.35.226
6 100.2.4.116
84 100.43.83.137
33 101.119.18.35
3 101.199.108.50
1 101.226.168.196
1 101.226.168.198
2 101.226.33.222
4 103.245.44.13
1 103.247.192.5
1 103.25.13.22
最大のカウント数のIPアドレスを見つけるために、再度sort
します。昇順に並ぶので、最大カウント数は、最終行に表示されます。
admin@ip-172-31-27-155:/$ cat /home/admin/access.log | cut -d' ' -f 1 | sort | uniq -c | sort
...
102 209.85.238.199
113 50.16.19.13
273 75.97.9.59
357 130.237.218.86
364 46.105.14.53
482 66.249.73.135
つまり、66.249.73.135
が 最大の482回アクセスがありました。これを /home/admin/highestip.txt
に書き込みます。
admin@ip-172-31-27-155:/$ echo "66.249.73.135" > /home/admin/highestip.txt
Discussion
これと
このコマンドの結果ってなんで異なるんですかね?後者だと次のような結果が返ってきます
uniq
は 同じ行が連続している行の重複を取り除きます。 つまり、ソートしていないと、期待通り動きません。なので、uniq
の間にsort
が必要です。例えば、text.txt が、次のように、
130.237.218.86
の間に1.1.1.1
が挟まれていると、のように、
1.1.1.1
で分断されているので、前半で130.237.218.86
が2回。 後半で130.237.218.86
が3回存在していると出力されます。これを回避するために、予め
sort
します。なるほど!連続している場合に削除して数えているんですね!なるほどです,ありがとうございます!