通过 Apache 服务器日志排序时排除某些机器人

Exclude certain bots when sorting through Apache server logs

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

cat /var/log/apache2/proxy.example.com.access.log | awk -F'|' '{print  }' | 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  }' | grep -v "Googlebot" | sort -n | uniq -c | sort -nr | head -30

但我想排除多个机器人。

我也做了:

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

这似乎可行,但是 bash 语法是否适合通过管道传输多个 grep?

我找到了一种更简洁的方法来代替多个 'grep -v'。我用了egrep:

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

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

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

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

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

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

或者,您可以使用 "blacklist" 文件,并执行如下操作:

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

其中 blacklist.txt 的内容是:

Applebot
Googlebot
bingbot

...这样做的好处是,当你发现一个新的条目你想忽略时,你可以将它添加到黑名单而不是修改你的脚本...它也非常可读。

edit:您还可以将 -r 参数移动到第一个 sort 并完全避免第二次调用。此外,因为您正在使用 awk,您可以完全摆脱 grep(请注意,以使用正则表达式为代价,但由于它 已经 处理文件,您可能会在 i/o):

上节省更多时间
cat /var/log/apache2/proxy.example.com.access.log | awk -F'|' '!/Applebot|Googlebot|bingbot/{print  }' | sort -nr | uniq -c | head -30

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

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

并且由于您知道字段的位置,您还可以使用 sed,这将比使用 awk 更快……我将其作为练习留给 reader(请记住索引搜索结果:ls | sed -n 's/\(.*\)\.txt//p' 导致所有“*.txt”文件在没有文件扩展名的情况下打印出来)