如何在Ansible 2.9中使用Replace模块删除指定区间内以#开头的行?
解决Ansible 2.9中replace模块跨多行删除注释的问题
你的问题很典型——Ansible 2.9版本的replace模块里,before和after参数的正则匹配默认是单行模式,没办法跨多行捕获你要处理的区块,所以你原来的写法没法准确选中# END ANSIBLE MANAGED BLOCK之后到第一个小写字母开头行之间的所有注释行。
解决方案:用多行正则直接匹配目标区块
我们可以绕过before/after参数,直接写一个多行正则表达式来匹配整个需要删除的区块,然后替换成只保留# END ANSIBLE MANAGED BLOCK这一行。
修改后的Ansible任务如下:
- name: Clean up unwanted comments after ANSIBLE managed block replace: path: /etc/subuid # 匹配# END行 + 后续所有以#开头的行,直到遇到小写字母开头的行 regexp: '(# END ANSIBLE MANAGED BLOCK\n)(#.*\n)+(?=[a-z])' # 替换时只保留捕获的# END行 replace: '\1' flags: - MULTILINE
正则表达式详解
让我们拆解一下这个正则的作用:
(# END ANSIBLE MANAGED BLOCK\n):用括号捕获# END ANSIBLE MANAGED BLOCK这一行(包括换行符),作为分组1,替换时会保留这部分内容。(#.*\n)+:匹配一个或多个以#开头的行(包括空注释行,比如#\n),+表示至少匹配一次。(?=[a-z]):正向预查,确保匹配的区块后面紧跟的是小写字母开头的行(也就是你要保留的userabc:1000001:65536这一行),这样就不会误删后续的内容。
为什么原来的写法行不通?
你原来的任务里,after: '# END ANSIBLE'和before: '^[a-z]*'都是单行匹配逻辑:
after只会定位到包含# END ANSIBLE的那一行,不会扩展到后续的多行。before只会匹配单行开头的小写字母,没办法跨多行找到区块的结束位置。
这就导致replace只能替换单个符合regexp的行,而不是整个目标区块。
验证效果
你可以先在目标服务器上用命令行测试这个正则的效果:
ansible <your_host> -m replace -a "path=/etc/subuid regexp='(# END ANSIBLE MANAGED BLOCK\n)(#.*\n)+(?=[a-z])' replace='\1' flags='MULTILINE'"
执行后查看/etc/subuid,应该会得到你期望的结果:只保留# END ANSIBLE MANAGED BLOCK,后续的注释行全部被删除,直接衔接userabc:1000001:65536。
内容的提问来源于stack exchange,提问作者sam99
相关产品推荐
相关产品推荐

