Today I found myself needing to extract the value of a json key that contained a dot (‘.’). As usual, json_query to the rescue, except that it didn’t work, returning an empty value. With a little bit of digging and trial and error testing, the solution presented itself. The key is to enclose the json key in quotes and then escape them.
Here is an example json file:
{
"menu": {
"id": "file",
"value": "File",
"popup": {
"dot.key": [{
"value": "New",
"onclick": "CreateNewDoc()"
},
{
"value": "Open",
"onclick": "OpenDoc()"
},
{
"value": "Close",
"onclick": "CloseDoc()"
}
]
}
}
}
And an example ansible playbook:
- name: json manipulation
gather_facts: no
hosts: localhost
vars:
json_var: "{{ lookup('file', 'file.json') | from_json }}"
tasks:
- name: get "menu.item" from json
set_fact:
json_out: "{{ json_var | json_query('menu.popup.\"dot.key\"[].value') }}"
We can clearly see the result:
PLAY [json manipulation] ******************************************************************************************************************************************************************************************
META: ran handlers
TASK [get "menu.item" from json] **********************************************************************************************************************************************************************************
task path: /tmp/1/1.yaml:7
ok: [localhost] => {
"ansible_facts": {
"json_out": [
"New",
"Open",
"Close"
]
},
"changed": false
}
META: ran handlers
META: ran handlers
PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0
PS: In this case we have 3x keys under “dot.key”. We obtain all of them in our result because we are selecting the whole dictionary ( ‘\”dot.key\”[]’ ) — notice the square brackets. We insert a number here and select the position of the key we want to get the value for. If for instance we would only need the 2nd key, we would use ‘\”dot.key\”[1]’ — “0” being the first value