我有一个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
除非有人有更好的方法,否则这对我来说非常有效。