我有一个定期运行的 shell 脚本,它的以下部分会导致速度变慢。
grep -v -f RemoveTheseGoodIPs.txt FromTheseShadyIPs.txt > RemainingBadIPs.txt
有用。只需 156 秒即可给出输出。我希望找到一种更快的处理方法,同时又易于理解且优雅。
对于上下文:“FromTheseShadyIPs.txt”是 200k 可疑 IP 地址的列表,“RemoveTheseGoodIPs.txt”是 3k 良好 IP 的白名单文件。最终,我生成了一个黑名单,我的外部防火墙可以参考,但我不希望我的 3k 良好 IP 出现在我的黑名单中。如果有帮助,两个文件中 IP 的顺序并不重要,并且它们已经在每个文件中进行了重复数据删除。处理服务器在不错的规格上运行 Debian 9。
答案1
尝试添加该-F
选项。它不执行任何正则表达式处理,只是将输入解释为字符串文字。
答案2
您的脚本存在比执行速度更重要的问题,它还会以两种方式遇到错误匹配:
- 正则表达式与字符串:当您应该使用字符串比较时,您正在使用正则表达式比较。正如所写,
.
RemoveTheseGoodIPs.txt 中的 IP 地址中的 s 将匹配 FromTheseShadyIPs.txt 中的任何字符,并且 - 部分与完整:当您应该使用全行比较时,您正在使用部分行比较。正如所写,RemoveTheseGoodIPs.txt 中较短的 IP 地址将与 FromTheseShadyIPs.txt 中包含该地址的任何 IP 地址匹配
鉴于此,您当前的脚本几乎肯定会从 FromTheseShadyIPs.txt 中删除RemoveTheseGoodIPs.txt 中不存在的 IP 地址,从而有效地破坏您的防火墙。
例如,如果包含RemoveTheseGoodIPs.txt1.2.3.4
并包含FromTheseShadyIPs.txt 911.253.456.789
,那么您的grep将删除第二个IP地址,因为您正在执行部分行正则表达式匹配,而不是您需要的全行字符串匹配:
$ head RemoveTheseGoodIPs.txt FromTheseShadyIPs.txt
==> RemoveTheseGoodIPs.txt <==
1.2.3.4
==> FromTheseShadyIPs.txt <==
9.8.7.6
911.253.456.789
6.7.8.9
$ grep -v -f RemoveTheseGoodIPs.txt FromTheseShadyIPs.txt
9.8.7.6
6.7.8.9
你应该使用
$ grep -vFxf RemoveTheseGoodIPs.txt FromTheseShadyIPs.txt
9.8.7.6
911.253.456.789
6.7.8.9
使您的脚本发挥作用。这是-F
用于字符串而不是正则表达式比较,以及-x
全行而不是部分比较。这可能也比您当前的脚本更快,但更重要的区别是它可以稳健地工作。
如果您的 grep 不支持任何这些选项,并且您无法获得支持的版本,则可以将以下内容与任何 awk 一起使用:
$ awk 'NR==FNR{a[$0]; next} !($0 in a)' RemoveTheseGoodIPs.txt FromTheseShadyIPs.txt
9.8.7.6
911.253.456.789
6.7.8.9
作为@Paul_Pedant 在评论中提到无论如何,使用 awk 可能比 grep 更快,具体取决于您的 grep 和 awk 实现。