如何在Ansible中对字典列表指定键值执行regex_replace?
Ansible CDP邻居接口名缩写转换解决方案
解决思路
要针对解析后的字典列表中指定键(LOCAL_INTERFACE、NEIGHBOR_INTERFACE)的值做格式转换,必须保留字典结构,避免把列表或字典转成字符串。以下是两种可靠的原生Ansible实现方法:
方法一:循环遍历+字段替换(直观易维护)
通过set_fact循环处理每个字典,替换目标字段后重新构建列表:
- name: 转换CDP邻居接口名缩写 set_fact: cdp_neighbors_processed: "{{ cdp_neighbors_processed | default([]) + [item | combine(updated_fields)] }}" loop: "{{ neighbors_raw.stdout[0] | ansible.netcommon.parse_cli_textfsm('templates/cisco_ios_show_cdp_neighbors.textfsm') }}" vars: updated_local: "{{ item.LOCAL_INTERFACE | regex_replace('^(Ten) ', 'Te') | regex_replace('^(Gig) ', 'Gi') }}" updated_neighbor: "{{ item.NEIGHBOR_INTERFACE | regex_replace('^(Ten) ', 'Te') | regex_replace('^(Gig) ', 'Gi') }}" updated_fields: LOCAL_INTERFACE: "{{ updated_local }}" NEIGHBOR_INTERFACE: "{{ updated_neighbor }}"
loop遍历解析后的字典列表,逐个处理每个邻居条目- 用
regex_replace精准替换接口前缀:Ten→Te、Gig→Gi combine将原字典与更新后的字段合并,保留其他键值不变- 逐步构建处理后的
cdp_neighbors_processed列表
方法二:Map+合并操作(简洁高效)
利用map对每个字典执行合并替换,无需显式循环:
- name: 转换CDP邻居接口名缩写 set_fact: cdp_neighbors_processed: >- {{ neighbors_raw.stdout[0] | ansible.netcommon.parse_cli_textfsm('templates/cisco_ios_show_cdp_neighbors.textfsm') | map('combine', { 'LOCAL_INTERFACE': item.LOCAL_INTERFACE | regex_replace('^(Ten|Gig) ', '\g<1>'[:2]), 'NEIGHBOR_INTERFACE': item.NEIGHBOR_INTERFACE | regex_replace('^(Ten|Gig) ', '\g<1>'[:2]) }) | list }} vars: item: "{{ item }}"
- 正则
^(Ten|Gig)匹配接口前缀,\g<1>[:2]直接取前缀的前两个字符,一次正则完成两种替换 map('combine', ...)对每个字典执行字段替换,保持原有结构| list将map对象转换为标准列表,确保后续操作正常识别
之前方法失效原因
- 直接对整个列表用
regex_replace:会把列表转为字符串后替换,最终得到字符数组,完全丢失字典结构 - 单独使用
map('regex_replace'):会把字典本身转为字符串进行替换,结果是字符串而非字典,破坏了原数据结构
内容的提问来源于stack exchange,提问作者Appleoddity
相关产品推荐
相关产品推荐

