【问题标题】:In Ansible/Jinja is there a way to regex_replace strings with integers using a dictionary of k:v pairs?在 Ansible/Jinja 中,有没有一种方法可以使用 k:v 对的字典将字符串替换为整数?
【发布时间】:2020-03-13 13:42:14
【问题描述】:

注意:原始问题在此处扩展:Is there a way in Ansible to replace a dictionary value based on k:v lookup to another dictionary?

我有 3 个字典,前 2 个是 k:v 和 string:integer 类型值;我的第三个字典是字符串:字符串的 k:v,我想先用 dict #1 循环,然后用 k:v 替换 k,然后用 dict #2 替换,但用 k:v 替换 v。

"dict_1": {
    "office-core01": 85,
    "office-core02": 86,
    "office-fw01": 87,
    "office-fw02": 88,
    "office-server-sw01": 91,
    "office-vpn01": 92,
    "office-vpn02": 93
}
"dict_2": {
    "con1": 129,
    "con2": 130,
    "con3": 131,
    "con4": 132,
    "con5": 133,
    "con6": 134,
    "con7": 135,
    "con8": 136,
    "con9": 137
}
"dict_3": {
    "office-core01": "con1", 
    "office-core02": "con2", 
    "office-fw01": "con3", 
    "office-fw02": "con4", 
    "office-server-sw01": "con7", 
    "office-vpn01": "con5", 
    "office-vpn02": "con6"
}

最后我需要一个包含 k:v 对整数的字典;例如,在第一次迭代中,我需要将 dict_3 中的主机名/密钥 (office-core01) 替换为 dict_1 (85) 中的值,然后第二次运行以替换端口/values (con1) 替换为 dict_2 (129) 中的键,但是使用 Vladimir 在原始问题中提供的代码抱怨 object of type 'int' has no len()

包含任务(console-portid.yml):

---
  - name: Replace Console Hostname ID
    set_fact:
      port_mapping: "{{ port_mapping | difference([item]) +
                        [dict(my_value | zip(my_keys))] }}"
    vars:
      my_key: "{{ item.keys() | list }}"
      my_value: "{{ item.values() | list }}"
      my_keys: "{{ my_key | map('regex_replace', port_id.key, port_id.value) | list }}"
    loop: "{{ dict_3 | dict2items }}"

调用:

- name: Replace Device Console Ports ID
  include_tasks: console-portid.yml
  loop: "{{ dict_1 | dict2items }}"
  loop_control:
    loop_var: port_id

【问题讨论】:

    标签: regex dictionary ansible jinja2


    【解决方案1】:

    问:“我想把office-core01:con1变成85:129”

    A:下面的任务完成了这项工作

        - set_fact:
            dict_3a: "{{ dict_3a|default({})|
                         combine({dict_1[item.key]: dict_2[item.value]}) }}"
          loop: "{{ dict_3|dict2items }}"
        - debug:
            var: dict_3a
    

        "dict_3a": {
            "85": 129, 
            "86": 130, 
            "87": 131, 
            "88": 132, 
            "91": 135, 
            "92": 133, 
            "93": 134
        }
    

    问:“key是string而value还是integer有什么原因吗?”

    A:变量的内部类型被保留。除非由DEFAULT_JINJA2_NATIVE 配置,否则变量评估为字符串。引用 “此选项在模板操作期间保留变量类型。这需要 Jinja2 >= 2.10。”


    问:“key 是 string 而 value 还是 integer 有什么原因吗?key 总是必须是 string 吗?”

    A:按键没有限制。引用自3.2.1.1. Nodes

    “一个 YAML 节点代表一个单一的原生数据结构。这些节点具有以下三种类型之一的内容:标量、序列或映射。此外,每个节点都有一个标签,用于限制可能的集合内容可以具有的值。”

    "映射:映射节点的内容是一组无序的键:值节点对,限制每个键都是唯一的。YAML 对节点没有进一步的限制。特别是键可以是任意的 odes,同一个节点可以用作多个键值对的值,并且映射甚至可以将自身包含为键或值(直接或间接)。”

    【讨论】:

    • 不完全是,最后我想把office-core01: con1变成85: 129,但是上面的代码给了我一个可以尝试的新方向。基本上用 3a + 3b 创建一个新字典,每个字典中的值都按顺序排列。
    • 谢谢。键是字符串而值仍然是整数是否有原因?键总是必须是字符串吗?
    【解决方案2】:
    ---
    - hosts: localhost
      gather_facts: no
      tasks:
      - name: Loop over dict_3
        debug:
          msg: "{{ item.key }}: {{ item.value }}"
        with_items: "{{ lookup('dict', dict_3) }}"
    
      - name: Loop over dict_3 with replacements
        debug:
          msg: "{{ dict_1[item.key] }}: {{ dict_2[item.value] }}"
        with_items: "{{ lookup('dict', dict_3) }}"
    
      - name: Create new dictionary
        set_fact:
          dict_4: "{{ dict_4|default({}) | combine( {dict_1[item.key]: dict_2[item.value]} ) }}"
        with_items: "{{ lookup('dict', dict_3) }}"
    
      - name: Show dict_4
        debug:
          var: dict_4
    

    【讨论】:

    • 啊,这很酷,所以这是我的完整字典中的输出(仅显示 1 个条目):ok: [localhost] => (item={'key': u'duboff04-core01', 'value': u'con1'}) => { "msg": "85: 129" ok: [localhost] => (item={'key': u'duboff04-core01', 'value': u'con1'}) ok: [localhost] => { "dict_4": { "85": 129
    • 奇怪的是,原来是整数的新键现在是字符串,但值仍然是 int..
    • 即使在group_vars/all/ 文件中将其作为整数输入,密钥仍然以字符串形式出现。
    • 对,我明白了,所以可能是由字典的组合过滤器强制执行的。无论如何它很棒,我至少可以使用它,干杯。
    猜你喜欢
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 2012-02-25
    • 2016-01-19
    相关资源
    最近更新 更多