5

我有一个如下所示的源 json 文档:

# Source json
{
  "nics": {
    "vlan_internal": {
      "mac": "aa:aa:aa:aa:aa:aa"
    },
    "vlan_external": {
      "mac": "aa:aa:aa:aa:aa:bb"
    }
  }
}

使用 ansible 的json_query过滤器(使用 jmespath),我想操作上面的 json,以便输出 json 文档如下所示:

# Desired output json
{
  "vlan_internal": "aa:aa:aa:aa:aa:aa",
  "vlan_external": "aa:aa:aa:aa:aa:ab"
}

似乎我应该使用某种多选散列,但我找不到将 vlan 名称(源 json 文档中的散列键,而不是散列值)放入输出 json 文档的好方法。

我不会提前知道 vlan 的名称,所以我不能硬编码vlan_internalvlan_external进入 jmespath 表达式。

我最接近的是这个 jmespath 表达式:

nics.{ vlans: keys(@), macs: *.mac }

这会产生一个几乎有用的输出 json 文档:

{
  "vlans": [
    "vlan_internal",
    "vlan_external"
  ],
  "macs": [
    "aa:aa:aa:aa:aa:aa",
    "aa:aa:aa:aa:aa:bb"
  ]
}

如果保证 vlan 名称列表的顺序和 mac 地址列表的顺序与源 json 文档的顺序相同,这将对我有用。但是 jmespath 规范非常清楚地表明该keys()函数不需要以任何特定顺序返回结果。由于我需要将 vlan 名称与正确的 mac 地址配对,因此这对我不起作用。

有人知道用 jmespath 完成此任务的方法吗?

4

2 回答 2

1

只有 JMESPath 你可以使用这个查询:

@.nics | {vlan_internal: @.vlan_internal | values(@)[0], vlan_external: @.vlan_external | values(@)[0]}

有了这个你的源 JSON,你会得到:

{
  "vlan_internal": "aa:aa:aa:aa:aa:aa",
  "vlan_external": "aa:aa:aa:aa:aa:bb"
}
于 2019-07-22T13:19:38.977 回答
0

首先,我不确定您是否应该经历所有这些麻烦。如果您不确定要获得的女巫钥匙,那么您可能会遍历整个 json,因此您知道自己的item钥匙。

不过,如果您只想导出一个新的 json,我无法找到使用本机 JMESPath 的方法。相反,我使用了一个 ansiblewith_dict循环,如下所示:

     - name: Create new nic_dict json
       set_fact:
          nic_dict: "{{ {item.key: item.value.mac} | combine(nic_dict | default({})) }}"
       with_dict: "{{ nics }}"

现在您可以使用如下所示的nic_dict

"nic_dict": {
    "vlan_external": "aa:aa:aa:aa:aa:bb",
    "vlan_internal": "aa:aa:aa:aa:aa:aa"
}
于 2017-12-23T18:52:58.357 回答