有时我想从我的 Apache 日志文件中 grep CIDR 范围。这对于落在自然边界(/8、/16 和 /24)上的范围来说很容易,但对于其他范围(例如 /17 和 /25)就不那么容易了。
例子:
# 192.168.0.0/16: (easy)
grep " 192\.168\." access_log
# 192.168.128.0/17: (more thought required)
grep -E " 192\.168\.(12[89]|1[3-9][0-9]|2[0-5][0-9])\." access_log
# 192.168.0.0/17: (more thought required)
grep -E " 192\.168\.([0-9]|[0-9][0-9]|1[01][0-9]|12[0-7])\." access_log
# 192.168.128.0/18: (straining my brain)
grep -E " 192\.168\.(1[2-8][0-9]|19[01])\." access_log
这些正则表达式会忽略包含前导零的 IP 地址,例如192.168.001.001
,这在 Apache 日志文件中不是问题,但可能在其他日志文件中。打印机似乎特别喜欢前导零。将可选的零添加到正则表达式中很容易,但这只会让整个事情变得更加困难。必须有更简单的方法。
有没有一种简单的方法可以从文件中选择与任何 CIDR 范围匹配的行?
花哨的正则表达式扩展将被视为不同的工具(例如,awk
如果perl
有必要,但我希望它成为一个单行工具),如果它们使工作更容易的话。理想情况下,我想要的是像
grep "[:CIDR 192.168.128.0/18:]" access_log
将 CIDR 范围转换为适当的正则表达式的工具也可以。
$ cidr2regex 192.168.0.0/18
192\.168\.(1[2-8][0-9]|19[01])\.[0-9]{1,3}
或者
$ grep -E "$(cidr2regex 192.168.0.0/18)" access_log
如果您的答案还涵盖 IPv6,则可加分。
毫不奇怪,有一个工具可以做到这一点:
grepcidr
.默认情况下,它不包含在我所知道的任何系统中,但您可以从此处下载它,它也在 Ubuntu 软件包存储库和 FreeBSD 端口集合中。
(2.0 版也适用于 IPv6 网络)
最近发布的
rgxg
命令行工具生成匹配 CIDR 块中所有地址的正则表达式:或者
有关详细信息,请参阅https://rgxg.github.io。