jmespath:如何搜索字典结构的字典

问题描述

本教程中有一个搜索示例:

{
  "machines": [
    {"name": "a","state": "running"},{"name": "b","state": "stopped"},"state": "running"}
  ]
}
In [68]: jmespath.search("machines[?state=='running'].name",p)
Out[68]: ['a','b']

但是,我的结构使用字典而不是列表,例如:

In [64]: q={
    ...:   "machines": {
    ...:     "m1":     {"name": "a",...:     "m2":     {"name": "b",...:     "m3":     {"name": "c","state": "running"}
    ...:     }
    ...:     }

我对此进行的其他尝试均失败了:

In [65]: jmespath.search("machines[?state=='running'].name",q)
# no output
In [66]: jmespath.search("machines.*[?state=='running'].name",q)
Out[66]: []

In [67]: jmespath.search("machines[*][?state=='running'].name",q)
# no output

如何执行此搜索

解决方法

您可以使用* wildcard expression从哈希中选择所有值:

>>> jmespath.search("machines.*",q)
[{'name': 'a','state': 'running'},{'name': 'b','state': 'stopped'},{'name': 'c','state': 'running'}]

现在您具有与以前相同的结构,因此可以向其中添加[?state=='running'].name。请将上面的表达式放在括号中,希望将其应用于通配符的数组输出,而不是应用于machines映射中的每个单独的值:

(machines.*)[?state=='running'].name

或使用pipe expression

machines.* | [?state=='running'].name

两者都能为您提供所需的输出:

>>> jmespath.search("(machines.*)[?state=='running'].name",q)
['a','c']
>>> jmespath.search("machines.* | [?state=='running'].name",'c']