Ansible regex_replace 字典列表中特定键的值

问题描述 投票:0回答:1

我已经为此苦苦挣扎了一段时间。我有一个这样的字典列表,它是通过使用

neighbors_raw.stdout[0] | ansible.netcommon.parse_cli_textfsm('templates/cisco_ios_show_cdp_neighbors.textfsm')
:

解析 Cisco CLI 输出而创建的
[
        {
            "CAPABILITY": "R S I",
            "LOCAL_INTERFACE": "Ten 1/1/1",
            "NEIGHBOR": "switch1.mydomain.com",
            "NEIGHBOR_INTERFACE": "Ten 1/0/4",
            "PLATFORM": "C9500-16X"
        },
        {
            "CAPABILITY": "S I",
            "LOCAL_INTERFACE": "Gig 1/1/2",
            "NEIGHBOR": "switch2.mydomain.com",
            "NEIGHBOR_INTERFACE": "Ten 1/1/1",
            "PLATFORM": "C9200L-48"
        }
]

我想将接口名称从

Ten 1/1/1
转换为
Te1/1/1
Gig 1/1/2
转换为
Gi1/1/2

我尝试过以下方法:

- name: PARSE NEIGHBORS
  debug:
    msg: "{{ neighbors_raw.stdout[0] | ansible.netcommon.parse_cli_textfsm('templates/cisco_ios_show_cdp_neighbors.textfsm') |
      regex_replace('Ten ', 'Te') |
      regex_replace('Gig ', 'Gi') }}"

输出看起来正确:

[
        {
            "CAPABILITY": "R S I",
            "LOCAL_INTERFACE": "Te1/1/1",
            "NEIGHBOR": "switch1.mydomain.com",
            "NEIGHBOR_INTERFACE": "Te1/0/4",
            "PLATFORM": "C9500-16X"
        },
        {
            "CAPABILITY": "S I",
            "LOCAL_INTERFACE": "Gi1/1/2",
            "NEIGHBOR": "switch2.mydomain.com",
            "NEIGHBOR_INTERFACE": "Te1/1/1",
            "PLATFORM": "C9200L-48"
        }
]

但是,如果我将此输出通过管道传输到任何其他命令中,它会将其视为字符数组:

- name: PARSE NEIGHBORS
  debug:
    msg: "{{ neighbors_raw.stdout[0] | ansible.netcommon.parse_cli_textfsm('templates/cisco_ios_show_cdp_neighbors.textfsm') |
      regex_replace('Ten ', 'Te') |
      regex_replace('Gig ', 'Gi') | list }}"

输出:

[
        "[",
        "{",
        "'",
        "N",
        "E",
        "I",
        "G",
        "H",
        "B",
        "O",
        "R",
        "'",
        ":",
        " ",
        "'",

如果我使用

zip
而不是
list
,也会发生同样奇怪的输出。

我也尝试过

map('regex_replace', 'Ten (.*)', 'Te\\1')
,但它只替换一次出现并将每个字典转换为字符串:

- name: PARSE NEIGHBORS
  debug:
    msg: "{{ neighbors_raw.stdout[0] | ansible.netcommon.parse_cli_textfsm('templates/cisco_ios_show_cdp_neighbors.textfsm') |
      map('regex_replace', 'Ten (.*)', 'Te\\1') }}"

输出:

[
        "{'NEIGHBOR': 'switch1.mydomain.com', 'LOCAL_INTERFACE': 'Te1/1/1', 'CAPABILITY': 'R S I', 'PLATFORM': 'C9500-16X', 'NEIGHBOR_INTERFACE': 'Ten 1/0/4'}",
        "{'NEIGHBOR': 'switch2.mydomain.com', 'LOCAL_INTERFACE': 'Gig 1/1/2', 'CAPABILITY': 'S I', 'PLATFORM': 'C9200L-48', 'NEIGHBOR_INTERFACE': 'Te1/1/1'}"
]

我还担心整个字典上的 regex_replace 将其视为字符串。我真的只想将转换应用到

LOCAL_INTERFACE
NEIGHBOR_INTERFACE
的特定值。

我怎样才能实现这一目标?

ansible
1个回答
0
投票

鉴于数据

  neighbors:
    - CAPABILITY: R S I
      LOCAL_INTERFACE: Ten 1/1/1
      NEIGHBOR: switch1.mydomain.com
      NEIGHBOR_INTERFACE: Ten 1/0/4
      PLATFORM: C9500-16X
    - CAPABILITY: S I
      LOCAL_INTERFACE: Gig 1/1/2
      NEIGHBOR: switch2.mydomain.com
      NEIGHBOR_INTERFACE: Ten 1/1/1
      PLATFORM: C9200L-48

创建更新属性的列表

  lifc: "{{ neighbors |
            map(attribute='LOCAL_INTERFACE') |
            map('regex_replace', 'Ten ', 'Te') |
            map('regex_replace', 'Gig ', 'Gi') |
            map('community.general.dict_kv', 'LOCAL_INTERFACE') }}"
  nifc: "{{ neighbors |
            map(attribute='NEIGHBOR_INTERFACE') |
            map('regex_replace', 'Ten ', 'Te') |
            map('regex_replace', 'Gig ', 'Gi') |
            map('community.general.dict_kv', 'NEIGHBOR_INTERFACE') }}"

给予

  lifc:
  - LOCAL_INTERFACE: Te1/1/1
  - LOCAL_INTERFACE: Gi1/1/2

  nifc:
  - NEIGHBOR_INTERFACE: Te1/0/4
  - NEIGHBOR_INTERFACE: Te1/1/1

zip列表并合并项目

  update: "{{ lifc | zip(nifc) | map('combine') }}"

给予

  update:
  - LOCAL_INTERFACE: Te1/1/1
    NEIGHBOR_INTERFACE: Te1/0/4
  - LOCAL_INTERFACE: Gi1/1/2
    NEIGHBOR_INTERFACE: Te1/1/1

zip更新并合并项目

  result: "{{ neighbors | zip(update) | map('combine') }}"

给你想要的

  result:
  - CAPABILITY: R S I
    LOCAL_INTERFACE: Te1/1/1
    NEIGHBOR: switch1.mydomain.com
    NEIGHBOR_INTERFACE: Te1/0/4
    PLATFORM: C9500-16X
  - CAPABILITY: S I
    LOCAL_INTERFACE: Gi1/1/2
    NEIGHBOR: switch2.mydomain.com
    NEIGHBOR_INTERFACE: Te1/1/1
    PLATFORM: C9200L-48

用于测试的完整剧本示例

- hosts: localhost

  vars:

    neighbors:
    - CAPABILITY: R S I
      LOCAL_INTERFACE: Ten 1/1/1
      NEIGHBOR: switch1.mydomain.com
      NEIGHBOR_INTERFACE: Ten 1/0/4
      PLATFORM: C9500-16X
    - CAPABILITY: S I
      LOCAL_INTERFACE: Gig 1/1/2
      NEIGHBOR: switch2.mydomain.com
      NEIGHBOR_INTERFACE: Ten 1/1/1
      PLATFORM: C9200L-48

    lifc: "{{ neighbors |
              map(attribute='LOCAL_INTERFACE') |
              map('regex_replace', 'Ten ', 'Te') |
              map('regex_replace', 'Gig ', 'Gi') |
              map('community.general.dict_kv', 'LOCAL_INTERFACE') }}"
    nifc: "{{ neighbors |
              map(attribute='NEIGHBOR_INTERFACE') |
              map('regex_replace', 'Ten ', 'Te') |
              map('regex_replace', 'Gig ', 'Gi') |
              map('community.general.dict_kv', 'NEIGHBOR_INTERFACE') }}"

    update: "{{ lifc | zip(nifc) | map('combine') }}"
    result: "{{ neighbors | zip(update) | map('combine') }}"

  tasks:

    - debug:
        var: lifc
    - debug:
        var: nifc
    - debug:
        var: update
    - debug:
        var: result
© www.soinside.com 2019 - 2024. All rights reserved.