【问题标题】:Ansible loop JSON array contains objects and replace each found element in JSON in fileAnsible 循环 JSON 数组包含对象并替换文件中 JSON 中找到的每个元素
【发布时间】:2021-09-09 20:51:52
【问题描述】:

我有这个 JSON:

[{
        "${foo1}": "somevalue1",
        "${foo2}": "somevalue2"
    }, {
        "${zoo1}": "somevalue111",
        "${zoo2}": "somevalue222"
}]

我需要在 ansible 和 JSON 数组中的每个对象中循环每个键/对值 我喜欢检查文件中是否存在密钥并将其替换为值。 例如: 如果在文件中我有

key1=${foo1}

它将被替换为

key1=somevalue1

我曾经有硬编码的 ansible 任务:

replace:
    path: "/myfile.txt"
    regexp: "{{ item.regexp }}"
    replace: "{{ item.replace }}"
  with_items:
    - { regexp: '${foo1}', replace: "new_value" }

我喜欢根据给定的 JSON 将其转换为动态搜索和替换

我像这样捕获 JSON :(这是修剪 YAML)

---
-
  gather_facts: false
  hosts: localhost
  name: test
  tasks:
    - name: debug
      debug:
        msg: "{{ AAA| to_json }}"
    - name: set fact
      set_fact:
         multi_parms: "{{ AAA| to_json }}"
    - name: debug multi_parms
      debug:
        var: multi_parms 

【问题讨论】:

  • 你怎么告诉key1应该是你的钥匙?只是有key 字符串加上index?或者所有的键名都可以是key

标签: json loops ansible


【解决方案1】:

j2 模板中的这段代码

  {% for  item in json_data %}
    {% for k, v in item.items() %}
   
      key{{loop.index}}  =  {{ v }}
 
     {% endfor %}
   {% endfor %} 

得到这个结果

  key1  =  somevalue1

   key2  =  somevalue2

   key1  =  somevalue111

  key2  =  somevalue222

这就是你要找的吗?

【讨论】:

  • 什么是j2模板?它是一个可靠的标准吗?
  • 是的,它是一个 jinja2 模板。如果您认为上述答案接近您的预期,我可以发布整个剧本。我不确定这是否满足您的需求。
  • 看起来很有趣,但是我现在如何使用包含所有键和值的替换任务在目标文件中进行搜索和替换?
  • 这种方法没有替代品。基本上,我正在读取您在 OP 中的数据,并分离 key, value 并将硬编码键分配给值
  • 我明白了,在获得键/值后如何实现替换?
【解决方案2】:

将 JSON 文件读入单个字典,例如

    - set_fact:
        my_data: "{{ my_data|d({})|combine(item) }}"
      loop: "{{ lookup('file', 'test.json') }}"

给予

  my_data:
    ${foo1}: somevalue1
    ${foo2}: somevalue2
    ${zoo1}: somevalue111
    ${zoo2}: somevalue222

给定一个 INI 文件,例如

shell> cat conf.ini
key1=${foo1}
key2=${foo2}
key3=xyz

将配置解析成字典,例如

    - set_fact:
        my_ini: "{{ dict(_keys|zip(_vals)) }}"
      vars:
        _lines: "{{ lookup('file', 'conf.ini').splitlines() }}"
        _regex: '^(.*)=(.*)$'
        _keys: "{{ _lines|map('regex_replace', _regex, '\\1') }}"
        _vals: "{{ _lines|map('regex_replace', _regex, '\\2') }}"

给予

  my_ini:
    key1: ${foo1}
    key2: ${foo2}
    key3: xyz

然后使用模块ini_file替换数据,例如

    - ini_file:
        path: conf.ini
        section:
        option: "{{ item }}"
        value: "{{ my_data[my_ini[item]] }}"
        no_extra_spaces: true
      loop: "{{ my_ini|list }}"
      when: my_ini[item] in my_data

给予

shell> cat conf.ini
key1=somevalue1
key2=somevalue2
key3=xyz

问:如何在目标文件中进行搜索和替换?

A:见下文每次迭代的“--diff”输出。

TASK [ini_file] ***************************************************
--- before: conf.ini (content)
+++ after: conf.ini (content)
@@ -1,3 +1,3 @@
-key1=${foo1}
+key1=somevalue1
 key2=${foo2}
 key3=xyz

changed: [localhost] => (item=key1)
--- before: conf.ini (content)
+++ after: conf.ini (content)
@@ -1,3 +1,3 @@
 key1=${foo1}
-key2=${foo2}
+key2=somevalue2
 key3=xyz

changed: [localhost] => (item=key2)
skipping: [localhost] => (item=key3)

【讨论】:

  • 我有点困惑,现在我有了键/值,我该如何在目标文件中进行搜索和替换?
  • 我已经添加了“--diff”输出。
  • 谢谢,问题是我没有使用ini文件,我使用YAML文件和文本文件进行搜索和替换,可以吗?
  • INI 文件和 YAML 文件和文本文件。特别是格式。如果出现问题,您应该使用minimal reproducible example 测试代码和edit 您的问题,而不是询问。请参阅How do comments work? 和“cmets 有什么用,什么时候不应该发表评论?”部分。特别是。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-08
  • 1970-01-01
  • 2022-01-14
相关资源
最近更新 更多