如何用Ansible的json_query将字典键值移至子键列表并展平
使用Ansible json_query转换字典结构
现有数据结构
seinfeld: - name: Jerry jobs: - comedian friends: - name: Elaine - name: Kramer - name: George jobs: - yankees friends: - name: Jerry - name: Susan
目标结构
new_list: - main: Jerry name: Elaine - main: Jerry name: Kramer - main: George name: Jerry - main: George name: Susan
正确的json_query解决方案
你之前的尝试问题出在merge的上下文和操作顺序不对,以下是可以直接得到目标结果的表达式:
seinfeld[].friends[] | merge(@, {main: `parent`.name})
在Ansible中直接使用的写法:
new_list: "{{ seinfeld | json_query('[].friends[] | merge(@, {main: `parent`.name})') }}"
表达式解释
seinfeld[]:遍历原列表中的每个条目friends[]:取出每个条目下的所有朋友元素,此时每个元素是{name: "XXX"}格式merge(@, {main:parent.name}):将当前朋友元素与一个新字典合并,新字典的main字段值为父条目(原seinfeld列表中的对应条目)的name值- 整个表达式执行后会自动展平为一维列表,正好匹配目标结构
Ansible Playbook示例
--- - name: Transform the Seinfeld data structure hosts: localhost vars: seinfeld: - name: Jerry jobs: - comedian friends: - name: Elaine - name: Kramer - name: George jobs: - yankees friends: - name: Jerry - name: Susan tasks: - name: Generate new_list using json_query set_fact: new_list: "{{ seinfeld | json_query('[].friends[] | merge(@, {main: `parent`.name})') }}" - name: Print the result debug: var: new_list
之前尝试失败的原因
你写的[].merge({friends: friends},{main: name}) [*].map(&merge({main: name}, @), friends)存在两个问题:
- 第一步merge后,后续
map操作中的name已经不在当前上下文,导致main字段值为null - 没有正确处理列表展平,最终结构会嵌套多层,不符合目标要求
内容的提问来源于stack exchange,提问作者Gianmarco
相关产品推荐
相关产品推荐

