jq Cheat Sheet
Example-wise the jq manpage is not really helpful. Let’s document some simple examples here…
To test queries live use jqplay.org
Output Formatting
If you do only care about output formatting (pretty print) run
jq . my.json
or when reading from a pipeline
cat my.json | jq
Note: for redirection you need to pass a filter too to avoid a syntax error:
jq . my.json > output.json
jq Extraction Examples
Consider this example document
{
"timestamp": 1234567890,
"report": "Age Report",
"results": [
{ "name": "John", "age": 43, "city": "TownA" },
{ "name": "Joe", "age": 10, "city": "TownB" }
]
}
To extract top level attributes “timestamp” and “report”
jq '. | {timestamp,report}'
To extract name and age of each “results” item
jq '.results[] | {name, age}'
To extract name and age as text values instead of JSON
jq -r '.results[] | {name, age} | join(" ")'
Filter this by attribute
jq '.results[] | select(.name == "John") | {age}' # Get age for 'John'
jq '.results[] | select((.name == "Joe") and (.age = 10))' # Get complete records for all 'Joe' aged 10
jq '.results[] | select(.name | contains("Jo"))' # Get complete records for all names with 'Jo'
jq '.results[] | select(.name | test("Joe\\s+Smith"))' # Get complete records for all names matching PCRE regex 'Joe\+Smith'
Avoid null
output when accessing non-existing keys
jq '.mykey | select(. != null)'
“Deep” Value Extraction
If you want to combine subkeys at different levels it won’t work like this
jq '.items[] | { metadata["created"], name }'
Instead you can access values like this
jq '.items[] | { "created" : .metadata["created"], name }'
Or like this
jq '.items[] | .metadata["created"], .name'
The drawback being, that you do not get a JSON output, but each value on a new line.
Accessing unknown keys
When processing objects you might not know about some keys, in this case use to_entries
. For example if you want to have all property fields of the following JSON:
echo '{
"name": "R1",
"type": "robot",
"prop1": "a5482na",
"prop2": null,
"prop3": 55
}' |\
jq '. | to_entries[] | select( .key | contains("prop"))'
will give you
{
"key": "prop1",
"value": "a5482na"
}
{
"key": "prop2",
"value": null
}
{
"key": "prop3",
"value": 55
}
Changing values with jq
Merging/overwriting keys
echo '{ "a": 1, "b": 2 }' |\
jq '. |= . + {
"c": 3
}'
Adding elements to lists
echo '{ "names": ["Marie", "Sophie"] }' |\
jq '.names |= .+ [
"Natalie"
]'
Delete values with jq
jq 'del(.somekey)' input.json
Merge JSON strings
For example merge three object lists:
echo '[ {"a":1}, {"b":2} ]' | \
jq --argjson input1 '[ { "c":3 } ]' \
--argjson input2 '[ { "d":4 }, { "e": 5} ]' \
'. = $input1 + . + $input2'
Merge files (since jq 1.4)
The following command will merge “somekey” from both passed files
jq -s '.[0] * .[1] | {somekey: .somekey}' <file1> <file2>
Handle Empty Arrays
When you want to iterate over an array, and the array you access is empty you get something like
jq: error (at <stdin>:3): Cannot iterate over null (null)
To workaround the optional array protect the access with
select(.my_array | length > 0)
Testing Types
$ echo '[true, null, 42, "hello", []]' | ./jq 'map(type)'
["boolean","null","number","string","array"]
Extracting key names
Given an JSON object like this
{
"animals": [
"dog": { },
"cat": { }
]
}
you can extract the names of the animals using
jq '.animals | keys'
Using jq in Shell Scripts
From https://www.terraform.io/docs/providers/external/data_source.html
Parsing JSON into env vars
To fill environment variables from JSON object keys (e.g. $FOO from jq query “.foo”)
export $(jq -r '@sh "FOO=\(.foo) BAZ=\(.baz)"')
To make a bash array
read -a bash_array < <(jq -r .|arrays|select(.!=null)|@tsv)
JSON template using env vars
To create proper JSON from a shell script and properly escape variables:
jq -n --arg foobaz "$FOOBAZ" '{"foobaz":$foobaz}'
URL Encode
Quick easy way to url encode something
date | jq -sRr @uri
String Concat
Concatenation like this:
echo '{ "object" : { "name": "banana", "color": "yellow" }}' |\
jq -r '.object | (.name)+" is "+(.color)'
will print banana is yellow
.
String Interpolation
Or using Interpolation:
echo '{ "object" : { "name": "banana", "color": "yellow" }}' |\
jq -r '.object | "\(.name) is \(.color)"'
will also print banana is yellow
.
Math Functions
jq can use math function from your libc. For example:
echo '{ "a": 1234.56 }' | jq '.a | round' # gives 1235
echo '{ "a": 1234.56 }' | jq '.a | floor' # gives 1235
echo '{ "a": 1234.56 }' | jq '.a | ceil' # gives 1234