每日一道shell腳本練習(02)

1. 題目

有日誌 1.log,部分內容如下:

112.111.12.248 - [25/Sep/2013:16:08:31 +0800]formula-x.haotui.com  "/seccode.php?update=0.5593110133088248" 200"http://formula-x.haotui.com/registerbbs.php" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;)"
61.147.76.51 - [25/Sep/2013:16:08:31 +0800]xyzdiy.5d6d.com "/attachment.php?aid=4554&k=9ce51e2c376bc861603c7689d97c04a1&t=1334564048&fid=9&sid=zgohwYoLZq2qPW233ZIRsJiUeu22XqE8f49jY9mouRSoE71" 301"http://xyzdiy.×××thread-1435-1-23.html" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"

請統計出每個IP的訪問量是多少?

2. 題目分析

根據日誌內容,可以看到IP地址就是第一段的內容,所以只需把1.log的第一段給過濾出來,然後進一步統計每個IP的數量即可。

過濾第一段,使用awk就可以了,而統計每個IP的訪問量則需要排序然後再計算數量,排序使用sort命令,統計每個IP的訪問量用uniq。

3. 具體shell命令

這道題,用shell腳本一條命令就足夠了:

awk  '{print  $1}'  1.log | sort   -n  | uniq  -c | sort  -n

解釋:

  1. awk 命令在分段方面比較有優勢,這裏的{print $1}將第一段打印出來,awk可以用-F指定分隔符,如果不指定分隔符,默認就以空白字符(比如空格、tab等),本題中,IP地址就是第一段。
  2. sort 命令就是排序,-n選項表示以數字的形式排序。如果不加-n,則以ASCII排序,本題的IP地址用數字的形式排序更易區分。
  3. uniq 命令用來去重複,一個文本如果有多行內容是一模一樣的,就使用uniq命令將相同的內容刪除,只保留一行。-c選項作用是計算重複的行數。所以,uniq -c 的作用正好就統計了ip的訪問量。不過,要注意,uniq去重要在排序之後進行。
  4. 最後的sort -n意思是按訪問量大小來排序,請求量越大的ip排在越後面。如果加一個-r選項,sort -nr,就是倒序排序。

4. 結語

這道題目還有另一種解法,明天再更新吧。

補充於4月11日
由於這篇文章在題目的例子裏有一些IP連接,所以每次修改發文官方都要重新審覈一天,我就不重新再寫一篇文章來寫另一種方法了。

這種方法最主要的區別,就是使用了awk的數組來統計結果,請看命令:

awk '{sum[$1]+=1};END{ for( a in sum)print (sum[a], a)}' 1.log | sort -nr | head -n 5

解釋一下,這條命令中$1 就表示日誌中的IP地址,用IP地址作爲數組的下標,每發現一個相同的IP地址,就統計數量加1;當awk遍歷日誌文件1.log 完畢,再循環輸出數組 sum 的結果,要注意數組的下標是 ip地址。

後面的 head -n 5 是爲了輸出出現訪問次數最高的5個訪問ip地址。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章