如何用正则匹配非注释行中的文件系统ID(Ansible环境)
问题场景
现有/etc/hosts内容如下:
#128.134.71.53 fs-1a07881b.efs.us-east-1.amazonaws.com varlogbackup 128.134.71.14 fs-a669fea7.efs.us-east-1.amazonaws.com confluence-shared 128.134.71.152 fs-1a07881b.efs.us-east-1.amazonaws.com varlogbackup
需要匹配非注释行中的EFS文件系统ID(如fs-a669fea7、fs-1a07881b),用于Ansible的lineinfile模块定位目标行并更新。
此前尝试的正则存在以下问题:
(fs-[\w]+)能匹配目标ID,但无法排除注释行^[^#].+(fs-[\w]+)可排除注释行并捕获目标ID,但无法仅返回捕获组- 正向预查
(?<=^\d+\.\d+\.\d+\.\d+ +)(fs-[\w]+)在测试工具中有效,但Ansible环境不支持
适配Ansible的解决方案
Ansible的lineinfile模块中,regexp参数用于匹配目标行(或行内片段)来定位需要替换的内容。结合需求,可采用以下两种兼容Ansible的正则方案:
方案1:简洁匹配非注释行中的目标FSID
将lineinfile的regexp修改为:
^[^#].*{{ item.fsid }}
正则逻辑:
^[^#]:匹配行首非#的行,直接排除注释行.*:匹配任意长度的中间字符{{ item.fsid }}:精准匹配目标文件系统ID
对应的Ansible任务代码:
vars: efs1: ip: 128.134.71.152 fsid: fs-1a07881b mount: varlogbackup efs_list: - "{{ efs1 }}" tasks: - name: 更新/etc/hosts中的EFS条目 ansible.builtin.lineinfile: path: /etc/hosts regexp: '^[^#].*{{ item.fsid }}' line: "{{ item.ip }} {{ item.fsid }}.efs.us-east-1.amazonaws.com {{ item.mount }}" loop: "{{ efs_list }}"
方案2:严格匹配行结构(避免误匹配)
如果需要确保只匹配IP + EFS域名 + 挂载点格式的行,可使用更严谨的正则:
^[^#]\d+\.\d+\.\d+\.\d+\s+{{ item.fsid }}\.efs\.us-east-1\.amazonaws\.com\s+\S+
正则逻辑:
^[^#]:排除注释行\d+\.\d+\.\d+\.\d+:匹配标准IP地址格式\s+:匹配一个或多个空格分隔符{{ item.fsid }}\.efs\.us-east-1\.amazonaws\.com:精确匹配EFS域名(.需转义)\s+\S+:匹配非空白字符组成的挂载点
该方案适合对格式要求严格、需避免误匹配的场景。
补充说明
Ansible基于Python正则引擎,对部分高级正则特性支持有限,因此优先采用行首匹配、基础字符匹配的规则,兼顾兼容性与稳定性。
内容的提问来源于stack exchange,提问作者shepster
相关产品推荐
相关产品推荐

