ということで、ヒット数上位3位から順に判定するawkスクリプトを作ろうと思っています。次のようなApache Webログに基づいてこれを行っています
192.168.198.92 - - [22/Dec/2002:23:08:37 -0400] "GET / HTTP/1.1" 200 6394 www.yahoo.com "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1...)" "-"
192.168.198.92 - - [22/Dec/2002:23:08:38 -0400] "GET /images/logo.gif HTTP/1.1" 200 807 www.yahoo.com "http://www.some.com/" "Mozilla/4.0 (compatible; MSIE 6...)" "-"
192.168.72.177 - - [22/Dec/2002:23:32:14 -0400] "GET /news/sports.html HTTP/1.1" 200 3500 www.yahoo.com "http://www.some.com/" "Mozilla/4.0 (compatible; MSIE ...)" "-"
192.168.72.177 - - [22/Dec/2002:23:32:14 -0400] "GET /favicon.ico HTTP/1.1" 404 1997 www.yahoo.com "-" "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3)..." "-"
192.168.72.177 - - [22/Dec/2002:23:32:15 -0400] "GET /style.css HTTP/1.1" 200 4138 www.yahoo.com "http://www.yahoo.com/index.html" "Mozilla/5.0 (Windows..." "-"
192.168.72.177 - - [22/Dec/2002:23:32:16 -0400] "GET /js/ads.js HTTP/1.1" 200 10229 www.yahoo.com "http://www.search.com/index.html" "Mozilla/5.0 (Windows..." "-"
192.168.72.177 - - [22/Dec/2002:23:32:19 -0400] "GET /search.php HTTP/1.1" 400 1997 www.yahoo.com "-" "Mozilla/4.0 JJohnJoJJJJJoJJoJJJJJoJJohJJJJJJJJJJJJohnJohJoJoJJJoJJ
これを行うには、次のようにします。
$1 ~ /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/ {
hitCounter[$1]++
notIndexed=1
for(i in ips) {
if (i==$1) { notIndexed=0 }
}
if(notIndexed==1) {
ips[indexx]=$1
indexx++
}
}
この行は IP を検出し、IP によってインデックス付けされた「hitCounter」配列でそのヒット カウントを増やします。次に、ips のリスト「ips」をチェックして、ヒットした IP が既にそこにあるかどうかを確認します。そうでない場合は、IP が「ips」配列に追加され、インデックス カウントが 1 つ増えます。理論的には、これを行うことにより、「ips」の各インデックスは「hitCounter」のインデックスと相関するはずです。最後に私は...
END {
indexxx=0
for (i in hitCounter) {
if (i>hitCounter[firstIP])
firstIP=ips[indexxx]
else if (i>hitCounter[secondIP])
secondIP=ips[indexxx]
else
thirdIP=ips[indexxx]
indexxx++
}
}
ここで、「hitCounter」の IP ヒット カウントを確認し、それらを 3 つの上位ヒット変数のヒットと比較し、IP ヒットが 3 つの上位ヒット変数の内容の 1 つよりも大きい場合は、それを現在の IP。
これは私にはうまくいくようで、出力として「192.168.72.177 192.168.198.92」が得られるはずですが、代わりに「192.168.198.92 192.168.198.92」が得られます。
なんで?
編集:申し訳ありませんが、これは「hitCounter」foreachループの直後に配置される最終結果を出力する方法です...
print "The most hits were from "firstIP" "secondIP" "thirdIP