使用Json src doc中的键,使用Jmespath进行多选哈希

时间:2017-05-05 16:13:00

标签: json ansible jmespath

我有一个源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 doc中的哈希键,而不是哈希值)输出json doc。

我之前不知道vlan的名字,因此我无法将vlan_internalvlan_external硬编码到jmespath表达式中。

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

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

这导致输出json doc几乎是有用的:

{
  "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实现此目的的方法吗?

2 个答案:

答案 0 :(得分:0)

首先,我不确定你是否应该经历所有那些喋喋不休。 如果你不确定是否需要使用女巫钥匙,那么你可以在整个json中进行迭代,所以,你知道你的item钥匙。

然而,如果您只想导出一个新的json,我无法找到使用本机JMESPath的方法。相反,我使用了一个ansible with_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"
}

答案 1 :(得分:0)

只有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"
}