There's an example of search in the tutorial going:
{
"machines": [
{"name": "a", "state": "running"},
{"name": "b", "state": "stopped"},
{"name": "b", "state": "running"}
]
}
In [68]: jmespath.search("machines[?state=='running'].name",p)
Out[68]: ['a', 'b']
However, my structure uses a dictionary rather than a list, e.g.:
In [64]: q={
...: "machines": {
...: "m1": {"name": "a", "state": "running"},
...: "m2": {"name": "b", "state": "stopped"},
...: "m3": {"name": "c", "state": "running"}
...: }
...: }
My different attempts to parse this have failed:
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
How can I perform this search?
You can use a *
wildcard expression to select all values from a hash:
>>> jmespath.search("machines.*", q)
[{'name': 'a', 'state': 'running'}, {'name': 'b', 'state': 'stopped'}, {'name': 'c', 'state': 'running'}]
Now you have the same structure as before, so you can add [?state=='running'].name
to it. Do put the above expression into parentheses, you want it to apply to the array output of the wildcard, not to each individual value in the machines
mapping:
(machines.*)[?state=='running'].name
or use a pipe expression:
machines.* | [?state=='running'].name
Both give you the desired output:
>>> jmespath.search("(machines.*)[?state=='running'].name", q)
['a', 'c']
>>> jmespath.search("machines.* | [?state=='running'].name", q)
['a', 'c']