在Ansible剧本中使用Shell命令提取iptables注释内容至文件的求助
解决iptables内容提取的问题
我来帮你搞定这个问题!你原来的awk和sed命令没达到预期是因为正则匹配的逻辑和用法不对,咱们一步步来修正,满足你的需求:把每行中-m comment到双引号的内容存入file1.txt,剩余内容存入file2.txt;不含comment的行直接存入file2.txt。
正确的awk解决方案
用awk可以一次完成两个文件的输出,逻辑更清晰,执行效率也更高:
awk '{ # 匹配从"-m comment"开始到第一个双引号结束的内容 if (match($0, /-m comment[^"]*"/)) { # 将匹配到的comment部分写入file1.txt print substr($0, RSTART, RLENGTH) > "file1.txt" # 将该行剩余的前后部分拼接后写入file2.txt print substr($0, 1, RSTART-1) substr($0, RSTART+RLENGTH) > "file2.txt" } else { # 没有comment字段的行直接写入file2.txt print > "file2.txt" } }' iptable.txt
命令解释
match($0, /-m comment[^"]*"/):用正则匹配整行内容,/-m comment[^"]*"/表示匹配从-m comment开始,到第一个双引号结束的所有字符([^"]*匹配任意非引号字符)。substr($0, RSTART, RLENGTH):提取匹配到的内容,RSTART是匹配起始位置,RLENGTH是匹配长度,这两个是awk的内置变量。- 对于不含comment的行,直接输出到file2.txt。
为什么你原来的命令失效?
- 你的awk命令问题:
awk '$NF == "-m.comment.*\""'用了==做精确匹配,而不是正则匹配(应该用~),而且$NF是取最后一个字段,显然comment部分不会是最后一个字段,逻辑完全错误。 - 你的sed命令问题:
sed 's/\/.*'是不完整的替换命令,既没有指定替换后的内容,也没有正确匹配你想要提取的部分,自然无法得到预期结果。
在Ansible Playbook中的使用方式
如果要在Ansible中执行这个命令,可以用shell模块,示例如下:
- name: Extract iptables comment sections to files shell: | awk '{ if (match($0, /-m comment[^"]*"/)) { print substr($0, RSTART, RLENGTH) > "file1.txt" print substr($0, 1, RSTART-1) substr($0, RSTART+RLENGTH) > "file2.txt" } else { print > "file2.txt" } }' iptable.txt args: chdir: /path/to/your/target/directory # 替换为你的iptable.txt所在目录
测试结果验证
用你提供的原始iptables内容测试:
file1.txt会输出:-m comment --comment "Echo Request" -m comment --comment "tcp"file2.txt会输出:-P INPUT ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A INPUT -p icmp -m state --state NEW -j ACCEPT -A INPUT -p tcp -m state --state NEW -j ACCEPT
内容的提问来源于stack exchange,提问作者Knightfox
相关产品推荐
相关产品推荐

