在对 Apache 服务器日志进行排序时排除某些机器人



我有一个bash脚本,可以对服务器日志中的最高点击进行排序,并打印IP地址和用户代理:

cat /var/log/apache2/proxy.example.com.access.log | awk -F'|' '{print $5 $11}' | sort -n | uniq -c | sort -nr | head -30

它打印出这样的结果:

COUNT   IP Address  User Agent
37586  66.249.73.223  "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
23960  84.132.153.226  "-" <--- I do need to see things like this
13246  17.58.103.219  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5 (KHTML, like Gecko) Version/8.0.2 Safari/600.2.5 (Applebot/0.1; +http://www.apple.com/go/applebot)" <--- But not this
10572  66.249.90.191  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246 Mozilla/5.0"
9505  66.249.73.223  "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
5157  66.249.73.193  "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

我不关心Googlebot,Bingbot,Applebot等机器人。有没有办法获得相同的格式,但不包括这些友好的机器人?

我能够通过以下方式排除Googlebot:

cat /var/log/apache2/proxy.example.com.access.log | awk -F'|' '{print $5 $11}' | grep -v "Googlebot" | sort -n | uniq -c | sort -nr | head -30

但我想排除多个机器人。

我也做了:

cat /var/log/apache2/proxy.example.com.access.log | awk -F'|' '{print $5 $11}' | grep -v "Googlebot" | grep -v "bingbot" | grep -v "Applebot" | sort -n | uniq -c | sort -nr | head -30

这似乎有效,但这是正确的 bash 语法来管道几个 grep 吗?

你也可以使用grep -F -v -e <phrase1> -e <phrase2> ... -e <phraseN>如下:

cat /var/log/apache2/proxy.example.com.access.log | awk -F'|' '{print $5 $11}' | grep -F -v -e "Googlebot" -e "bingbot" -e "Applebot" | sort -n | uniq -c | sort -nr | head -30

-F告诉 grep 将搜索字符串视为固定字符串......这通常比使用正则表达式快得多

-e允许您指定表达式。使用多个-e标志可以组合多个表达式以在单个 grep 命令中使用。

或者,您可以使用"黑名单"文件,并执行以下操作:

cat /var/log/apache2/proxy.example.com.access.log | awk -F'|' '{print $5 $11}' | grep -F -f blacklist.txt -v | sort -n | uniq -c | sort -nr | head -30

其中黑名单的内容.txt为:

Applebot
Googlebot
bingbot

。这样做的好处是,当您找到要忽略的新条目时,您可以将其添加到黑名单中,而不是修改脚本......它也非常具有可读性。

编辑:您还可以将-r参数移动到第一个sort,并完全避免第二次调用。另外,因为你使用的是awk,你可以完全摆脱 grep(请注意,以使用正则表达式为代价,但由于它已经在处理文件中的每一行,你可能会在 I/O 上节省更多时间(:

cat /var/log/apache2/proxy.example.com.access.log | awk -F'|' '!/Applebot|Googlebot|bingbot/{print $5 $11}' | sort -nr | uniq -c | head -30

我还建议摆脱领先的猫,因为awk将打开文件进行读取而无需修改(除非您告诉它修改文件(:

awk -F'|' '!/Applebot|Googlebot|bingbot/{print $5 $11}' /var/log/apache2/proxy.example.com.access.log | sort -nr | uniq -c | head -30

而且由于您知道字段的位置,因此您还可以使用比使用awk更快的sed......我把它留给读者练习(请记住索引的搜索结果:ls | sed -n 's/(.*).txt/1/p'导致所有"*.txt"文件被打印出来,没有文件扩展名(

我找到了一种更干净的方法来做到这一点,而不是多个"grep -v"。我使用了egrep:

cat /var/log/apache2/proxy.example.com.access.log | awk -F'|' '{print $5 $11}' | egrep -v "Googlebot|bingbot|Applebot" | sort -n | uniq -c | sort -nr | head -30

除非有人有更好的方法,否则这对我来说非常有效。

最新更新