`jq`, a lightweight JSON parser
jq is a lightweight JSON parser. Unfortunately the usage is quite esoteric and anything written about it makes it more confusing. In this post I tackle one of the functions of jq
: accessing values inside JSON objects.
You can either pipe stdout into jq
or use jq
with the following syntax:
$ jq -<flags> 'commands' <file>
Let’s say you have the following JSON string in a file called json-file
:
{"one":"first field", "two":"second field", "three":{"three_one":"3 1", "three_two":"3 2"}, "four":[{"four_one":"4 1", "four_one_b":"4 1 b"}, {"four_two":"4 2"}]}
You can make it human readable with .
(dot). The .
is like the root level /
in the shell:
$ jq '.' json-file
{
"one": "first field",
"two": "second field",
"three": {
"three_one": "3 1",
"three_two": "3 2"
},
"four": [
{
"four_one": "4 1",
"four_one_b": "4 1 b"
},
{
"four_two": "4 2"
}
]
}
# Note that if you pipe into `jq` you don't even need the dot
$ echo json-file | jq
Accessing the key:value pairs in the objects
Notice in this case we have a nested object in “three” and an array under “four” with 2 objects in that array.
So now to access the values of the top level:
$ jq '.["one"]' json-file
"first field"
$ jq '.["one", "two"]' json-file
"first field"
"second field"
$ jq '.["three"]' json-file
{
"three_one": "3 1",
"three_two": "3 2"
}
# Note the array denoted by the square brackets
$ jq '.["four"]' json
[
{
"four_one": "4 1",
"four_one_b": "4 1 b"
},
{
"four_two": "4 2"
}
]
# To iterate through all the fields at the first level:
$ jq '.[]' json-file
"first field"
"second field"
{
"three_one": "3 1",
"three_two": "3 2"
}
[
{
"four_one": "4 1",
"four_one_b": "4 1 b"
},
{
"four_two": "4 2"
}
]
In fact, you don’t need to use the indexing syntax and can use an object syntax:
$ jq '.one' json-file
"first field"
jq '.one, .two' json-file
"first field"
"second field"
How do we access the values inside “three”?
$ jq '.three.three_one, .three.three_two' json-file
"3 1"
"3 2"
# to iterate through all the values at this level
$ jq '.three[]' json-file
"3 1"
"3 2"
Now what about the array at “four”?
# List the level under "four", note the array `[`, `]`
$ jq '.four' json-file
[
{
"four_one": "4 1",
"four_one_b": "4 1 b"
},
{
"four_two": "4 2"
}
]
# To iterate through all the elements inside the array:
% jq '.four[]' json-file
{
"four_one": "4 1",
"four_one_b": "4 1 b"
}
{
"four_two": "4 2"
}
# Note that there are 2 objects inside this level.
# To access the elements inside the object, you have to use
# An array index (which is a zero index)
$ jq '.four[0]' json-file
{
"four_one": "4 1",
"four_one_b": "4 1 b"
}
# And
$ jq '.four[1]' json-file
{
"four_two": "4 2"
}
# This then gives us access to the objects at this level
$ jq '.four[0].four_one, .four[0].four_one_b' json
"4 1"
"4 1 b"
# To iterate through the object inside four[0]
$ jq '.four[0][]' json-file
"4 1"
"4 1 b"
We have only touched on how to access values inside nested objects and arrays in a JSON object using jq
. jq
has far more capabilities, including manipulating values inside the objects. More at a later date!