【问题标题】:Unable to remove entry from a file using Ansible regex无法使用 Ansible 正则表达式从文件中删除条目
【发布时间】:2020-05-13 13:29:49
【问题描述】:

注意:我正在为 Ansible 寻求解决方案。以下是问题描述:

我有一个文件filedet.yml,如下所示,但是这个yaml 可能包含更多的IP 和文件详细信息。

---
10.9.9.111:
  /tmp/test.jar:
    hash: e6df90d38fa86f0e289f73d79cd2cfd2a29954eb

  /tmp/best.jar:
    hash: e6df90d38fa86f0e289f73d79cd2cfd2a29954eb

10.8.8.44:
  /tmp/conf/extra/httpd-ssl.conf:
    hash: 1746f03d57491b27158b0d3a48fca8b5fa85c0c2

  /tmp/conf/httpd.conf:
    hash: 1746f03d57491b27158b0d3a48fca8b5fa85c0c2

我希望提取特定 IP 和文件详细信息,以便可以使用 state: absent 属性将其从 yaml 中删除。因此,所需的正则表达式应返回以下内容:

10.9.9.111:
  /tmp/test.jar:
    hash: e6df90d38fa86f0e289f73d79cd2cfd2a29954e

  /tmp/best.jar:
    hash: e6df90d38fa86f0e289f73d79cd2cfd2a29954eb

我决定将开始模式设置为“10.9.9.111”并搜索直到没有空格或换行符,这意味着直到它到达下一个 IP。

我准备了下面的正则表达式,它在http://regex101.com 上显示了正确的、所需的全文匹配。查看快照。

下面的正则表达式查询:

[^#](^10.9.9.111:)(.|\n)*^(?!( |\n))

相同的正则表达式与grep -Pzo 一起工作并返回所需的字符串。但是,正则表达式无法与 ansible 的 lineinfile 模块一起使用,因为它不会产生任何结果。

我希望此正则表达式或任何其他解决方案与 Ansible 一起使用,以便我可以从 yaml 中删除给定的 IP 及其文件详细信息

Ansible:

   - name: "Remove entry from file."
     lineinfile:
       path: "/app/filedet.yaml"
       regexp: "[^#](^10.9.9.111:)(.|\n)*^(?!( |\n))"
       state: absent

你能建议这里有什么问题吗?

【问题讨论】:

  • 在 POSIX *REs 中,正则表达式中间的抑扬符匹配正则抑扬符;它失去了作为特殊字符的意义。而 IIRC POSIX grep 无法执行多行匹配
  • grep 一次只检查一行;使用此工具无法真正指定应该跨越换行符的匹配项。
  • 我不是在寻找 grep 的解决方案,而是在寻找可以与 Ansible 一起使用的正则表达式
  • grep -Pzo 为我工作。但是我怎样才能让它与 Ansible 的 lineinfile 一起工作?

标签: regex grep ansible regex-negation regex-group


【解决方案1】:

问:“我希望提取 IP 和文件详细信息。”

答:使用include_vars。例如

    - include_vars:
        file: filedet.yml
        name: my_dict
    - debug:
        msg: "{{ my_dict['10.9.9.111'] }}"

    "msg": {
        "/tmp/best.jar": {
            "hash": "e6df90d38fa86f0e289f73d79cd2cfd2a29954eb"
        }, 
        "/tmp/test.jar": {
            "hash": "e6df90d38fa86f0e289f73d79cd2cfd2a29954eb"
        }
    }

问:“从文件中删除一个条目。”

A:使用模板。例如

$ cat filedet.yml.j2
{% for item in my_dict_keys %}
{{ item }}:
  {{ my_dict[item]|to_nice_yaml|indent(2) }}
{% endfor %}

下面的任务

    - set_fact:
        my_dict_keys:
          - "10.8.8.44"
    - template:
        src: filedet.yml.j2
        dest: filedet.yml

给予

$ cat filedet.yml
10.8.8.44:
  /tmp/conf/extra/httpd-ssl.conf:
      hash: 1746f03d57491b27158b0d3a48fca8b5fa85c0c2
  /tmp/conf/httpd.conf:
      hash: 1746f03d57491b27158b0d3a48fca8b5fa85c0c2

注意事项:

  • 为此目的使用lineinfile 是个坏主意

  • 问题中的数据不是有效的 YAML。关键是重复

10.9.9.111:
  /tmp/test.jar:
    hash: e6df90d38fa86f0e289f73d79cd2cfd2a29954eb
  /tmp/test.jar:
    hash: e6df90d38fa86f0e289f73d79cd2cfd2a29954eb

【讨论】:

  • 您能否获得包含所有 ip 和文件详细信息的模板,但在这种情况下我希望删除的 10.9.9.111 除外
  • 没有。我不能。模板很好。相反,您可以先测试您想要什么,然后使用所有相关详细信息更新您的问题。
  • 弗拉基米尔我用所有细节更新了这个问题。可以看看吗?
  • 在此处添加详细描述的新帖子:stackoverflow.com/questions/59948370/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-29
  • 2012-07-22
  • 2011-01-20
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多