Parsing with JQ
In these examples, you’ll be working with jq to extract specific JSON data. For more inforamtion please see the jq documentation located here.
{
"data": [
{
"gid": "001",
"name": "project_1",
"data_type": "json"
},
{
"gid": "002",
"name": "project_2",
"data_type": "json"
},
{
"gid": "003",
"name": "project_3",
"data_type": "json"
}
]
}
Using the example data above, you can use either of the 2 styles in parsing JSON data noted below.
Notation Name |
Example |
Output |
---|---|---|
dot notation |
$.data[0].gid |
001 |
bracket notation |
$.[‘data’][0][‘gid’] |
001 |
Note
In Ansible, bracket notation is preferred
Both of these examples reference the same value (001). Bracket notation always works. Dot notation can cause problems because some keys collide with attributes and methods of python dictionaries. Use bracket notation if you use keys which start and end with two uderscores (which are reserved for special meaning in python) or are any of the known public attributes. (add link from Ansible)
{
"dataCenter": [
{
"switch": [
{
"id": 1,
"manufacturer": "Cisco",
"model": "9600"
},
{
"id": 6,
"manufacturer": "Cisco",
"model": "9400"
},
{
"id": 2,
"manufacturer": "Juniper",
"model": "4300"
}
]
},
{
"routing": [
{
"id": 3,
"name": "ospf",
"dynamic": true
},
{
"id": 4,
"name": "isis",
"dynamic": true
},
{
"id": 5,
"name": "static",
"dynamic": false
}
]
}
]
}
Bracket Notation
Print out the json file starting at the root level object dataCenter
curl https://raw.githubusercontent.com/cwise24/snopsy/main/datacenter.json | jq '.["dataCenter"]'
Print out the array of objects under switch, notice that you must include the full array of objects in dataCenter as switch is found in that array:
curl https://raw.githubusercontent.com/cwise24/snopsy/main/datacenter.json | jq '.["dataCenter"][]["switch"]'
Another way we could express this, is to return only the first element of the dataCenter array:
curl https://raw.githubusercontent.com/cwise24/snopsy/main/datacenter.json | jq '.["dataCenter"][0]'
[
{
"id": 1,
"manufacturer": "Cisco",
"model": "9600"
},
{
"id": 6,
"manufacturer": "Cisco",
"model": "9400"
},
{
"id": 2,
"manufacturer": "Juniper",
"model": "4300"
}
]
Create a custom JSON object output based on keys:
curl https://raw.githubusercontent.com/cwise24/snopsy/main/datacenter.json | jq '.["dataCenter"][]["switch"][] | {manufacturer,model}'
{
"manufacturer": "Cisco",
"model": "9600"
}
{
"manufacturer": "Cisco",
"model": "9400"
}
{
"manufacturer": "Juniper",
"model": "4300"
}
Only output switches where the manufacturer is Cisco:
curl https://raw.githubusercontent.com/cwise24/snopsy/main/datacenter.json | jq '.["dataCenter"][]["switch"][] | select(.["manufacturer"] == "Cisco")'
{
"id": 1,
"manufacturer": "Cisco",
"model": "9600"
}
{
"id": 6,
"manufacturer": "Cisco",
"model": "9400"
}
Output only the model numbers
curl https://raw.githubusercontent.com/cwise24/snopsy/main/datacenter.json | jq '.["dataCenter"][]["switch"][] | select(.["manufacturer"] == "Cisco")["model"]'
"9600"
"9400"
Using variable substitution with jq
--arg - treats the variable as a string (Example --arg foo 123 will bind $foo to “123”)
--argjson - treats the variable as integer (Example --argjson foo 123, $foo will have the value 123)
-r - raw output - will directly to standard out; unformated
curl https://raw.githubusercontent.com/cwise24/snopsy/main/datacenter.json | jq --arg idnum Cisco '.["dataCenter"][]["switch"][] | select(.["manufacturer"] == $idnum)'
{
"id": 1,
"manufacturer": "Cisco",
"model": "9600"
}
{
"id": 6,
"manufacturer": "Cisco",
"model": "9400"
}
curl https://raw.githubusercontent.com/cwise24/snopsy/main/datacenter.json | jq --argjson idnum 4 '.["dataCenter"][]["routing"][] | select(.["id"] == $idnum)'
{
"id": 4,
"name": "isis",
"dynamic": true
}
Dot Notation
curl https://raw.githubusercontent.com/cwise24/snopsy/main/datacenter.json | jq --arg idnum Cisco '.dataCenter[].switch[] | select(.manufacturer == $idnum)'