python - 如何使用 Python grep 获取 Shorewall 规则文件中的 IP 地址
问题描述
如果我使用 python 创建一个包含要删除的 IP 列表的文件,然后将该文件作为正则表达式规则列表提供给 grep,我可以获得我想要的结果,但不能单独使用 python。
该脚本从 Microsoft 下载 Office365 规则更改的 JSON 源。
然后它只对“删除”更改起作用。
我试过使用 re 和一个简单的字符串比较,都没有产生任何结果或错误。
ips = changes['ips'] if 'ips' in changes else []
ip4s = [ip for ip in ips if '.' in ip]
for ip in ip4s:
ip_rule = 'net:' + ip
with open('/etc/shorewall/rules', 'r') as rules_file:
with open('/tmp/rules', 'w') as tmp_rules_file:
for line in rules_file:
if not ip_rule in line:
tmp_rules_file.write(line)
实际的脚本有 3 个部分用于正则表达式 URL、域和 IP。
前两个工作,但不是 IP 部分。它不会出现任何错误或任何更改。
应该发生的是它创建了一个临时文件,其中不包含应该删除的岸墙规则。
然后当我 vimdiff 旧规则文件和临时文件时,我可以看到需要删除的内容。
实际结果是两个文件完全相同。
在 python 之外的进一步测试表明应该删除 211 行。
我是 python 新手,所以假设我被某些东西绊倒了,只是看不到它。
解决方案
让我们用一个带有列表的小例子来试试这个,而不是使用文件。从长远来看,您可以做for line in file
或for line in list
可以制作一个可以将任何可迭代对象发送到其中的函数。这意味着您可以编写单元测试,显示最小的示例以获得帮助。
所以,让我们有我们的ips
ip4s=["1.1.1.1", "2.2.2.2"]
并输入和输出“文件”:
rules_file = ['net:1.1.1.1', 'net:3.3.3.3']
tmp_rules_file = []
(例如 - 假设您可以使用您的正则表达式以您需要的方式获取格式)
对。因此,当我们执行循环时:
for ip in ip4s:
ip_rule = 'net:' + ip
for line in rules_file:
if not ip_rule in line:
tmp_rules_file.append(line)
因此,对于每一ip4s
行,我们一次查看旧规则文件中的每一行。没有的每一行都"1.1.1.1"
被写入...
在此示例中,1.1.1.1
确实匹配第一个 IP,因此不写入tmp_rules_file
. 但是,3.3.3.3
不匹配,因此被写入tmp_rules_file
.
下一个 IP 是2.2.2.2
- 两行都不匹配,因此当您(再次)回顾整个文件时,规则文件的两行都被放入临时文件中,最终得到:
>>> tmp_rules_file
['net:3.3.3.3', 'net:1.1.1.1', 'net:3.3.3.3']
这表明出了什么问题。
要在一个列表中查找不在另一个列表中的内容,您可以使用列表推导:
[ip for ip in ip4s if 'net:'+ip not in rules_file]
这只是['2.2.2.2']
在这种情况下给出。
对于较大的数据,您可能需要使用集合并尝试集合差异操作。
您的问题的主要部分是针对文件的每一行检查一件事 - 如果它匹配一个,它将与其他不匹配,因此被写回。
推荐阅读
- kubernetes - 使用 CSI 机密驱动程序提供的保险库机密作为 Kubernetes 中的环境变量
- python - O365 API,转发电子邮件
- here-api - HERE 地理编码在多词搜索词上返回空响应
- google-apps-script - 如何根据您在谷歌表格中的标准操作数据?
- rust - 避免结构生锈中的生命周期参数?
- javascript - 文件上传暂停,显示模态窗口,继续上传
- r - 创建一个函数来计算给定向量的偏度
- c - Make 自动将 Objs 从 Headers 编译到 Archive 再编译到 Main 程序
- scala - SBT:如何确保提取本地快照依赖项?
- laravel - 无效参数(会话信息:headless chrome=91.0.4472.77)