Ansible json_query 将字典键/值移动到列表子键

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

我正在尝试用一行 json_query (和/或其他过滤器)编辑 ansible 中的字典,但是出了点问题,我无法弄清楚。 我有这个结构(带有示例数据)

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

name
键将添加到
friends
键的每个元素并将其展平到新列表。 我已经在混合 jmespath
map
merge
方面取得了一些进展,但至少有一个键始终为空或无效,一些随机测试是
[].merge({friends: friends},{main: name}) [*].map(&merge({main: name}, @), friends)

json filter ansible jmespath json-query
1个回答
0
投票

获取数据有更多选项。例如,

  tmp: "{{ seinfeld | json_query('[].[name, friends[].name]') }}"
  tmp: "{{ seinfeld | map(attribute='name') |
           zip(seinfeld | map(attribute='friends')
                        | map('map', attribute='name')) }}"

给出相同的列表

  tmp:
  - - Jerry
    - - Elaine
      - Kramer
  - - George
    - - Jerry
      - Susan

现在,您需要映射功能产品。不幸的是,这是不可能的。过滤器 json_query 也无法帮助您处理列表列表。所以,这是一个死胡同。

唯一的选择是Jinja 模板

  new_list: |
    {% filter from_yaml %}
    {% for name in tmp1 %}
    {% for friend in name.1 %}
    - {main: {{ name.0 }}, name: {{ friend }}}
    {% endfor %}
    {% endfor %}
    {% endfilter %}

给你想要的

  new_list:
  - main: Jerry
    name: Elaine
  - main: Jerry
    name: Kramer
  - main: George
    name: Jerry
  - main: George
    name: Susan

但是,您可以使用子元素轻松迭代列表。例如,

    - debug:
        msg: "main: {{ item.0.name }}, name: {{ item.1.name }}"
      loop: "{{ seinfeld | subelements('friends') }}"

给出(删节)

  msg: 'main: Jerry, name: Elaine'
  msg: 'main: Jerry, name: Kramer'
  msg: 'main: George, name: Jerry'
  msg: 'main: George, name: Susan'

是否需要new_list由您决定。

© www.soinside.com 2019 - 2024. All rights reserved.