bash jq - ghdrako/doc_snipets GitHub Wiki
- https://jqlang.github.io/jq/manual/
- https://earthly.dev/blog/jq-select/
- https://stedolan.github.io/jq/manual/
- https://stedolan.github.io/jq/tutorial/
- https://www.baeldung.com/linux/jq-command-json
- https://github.com/stedolan/jq/wiki/Cookbook
To test queries live use https://jqplay.org/
If you do only care about output formatting (pretty print) run
$ echo '{"fruit":{"name":"apple","color":"green","price":1.20}}' | jq '.'
{
"fruit": {
"name": "apple",
"color": "green",
"price": 1.2
}
}
jq . my.json
Note: for redirection you need to pass a filter too to avoid a syntax error:
jq . my.json > output.json
Being able to prettify JSON is particularly useful when we want to retrieve data from an API and see the response in a clear, readable format.
curl http://api.open-notify.org/iss-now.json | jq '.'
output=$(curl ... 2>/dev/null)
output=$(echo $output | jq .[0]
question=$(echo $output | jq .question)
$ curl https://api.github.com/repos/stedolan/jq
{
"id": 5101141,
"node_id": "MDEwOlJlcG9zaXRvcnk1MTAxMTQx",
"name": "jq",
"full_name": "stedolan/jq",
"private": false,
"owner": {
"login": "stedolan",
"id": 79765
},
"html_url": "https://github.com/stedolan/jq",
"description": "Command-line JSON processor",
"stargazers_count": 19967,
"watchers_count": 19967,
"language": "C",
"license": {
"key": "other",
"name": "Other",
"spdx_id": "NOASSERTION",
"url": null,
"node_id": "MDc6TGljZW5zZTA="
}
}
$ curl https://api.github.com/repos/stedolan/jq | jq ' .name'
"jq"
$ curl https://api.github.com/repos/stedolan/jq | jq ' .owner'
{
"login": "stedolan",
"id": 79765
}
$ https://api.github.com/repos/stedolan/jq | jq ' .owner.login'
"stedolan"
curl https://api.github.com/repos/stedolan/jq/issues?per_page=5 | jq '.[4]'
$ echo "[1,2,3,4,5]" | jq '.[2:4]'
[3,4]
$ echo "[1,2,3,4,5]" | jq '.[2:]'
[3,4,5]
$ echo "[1,2,3,4,5]" | jq '.[-2:]'
[4,5]
$ curl https://api.github.com/repos/stedolan/jq/issues?per_page=5 | jq '.[4].title'
All elements
curl https://api.github.com/repos/stedolan/jq/issues?per_page=5 | jq '.[].title'
jq lets you select the whole array []
, a specific element [3]
, or ranges [2:5]
and combine these with the object index if needed.
It ends up looking something like this:
jq '.key[].subkey[2]
$ echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[6:9]'
[
7,
8,
9
]
$ echo '[1,2,3,4,5,6,7,8,9,10]' | jq '.[:6]' | jq '.[-2:]'
[
5,
6
]
$ jq '.fruit | length' fruit.json
$ jq '.fruit.name | length' fruit.json
5 # fruit name property has five characters: “apple”.
applying the has function to each item in the array and looking to see if there is a name property
jq 'map(has("name"))' fruits.json
use the map function to apply operations to the elements in an array
jq 'map(.price+2)' fruits.json
minimum or maximum element of an input array, we can utilize the min and max functions
jq '[.[].price] | min' fruits.json
Selects all the fruit with a price greater than 0.5.
$ jq '.[] | select(.price>0.5)' fruits.json
$ jq '.[] | select(.color=="yellow")' fruits.json
$ jq '.[] | select(.color=="yellow" and .price>=0.5)' fruits.json
{
"name": "banana",
"color": "yellow",
"price": 0.5
}
jq --arg branch $branch '.[] | select(.name|match($branch)) | .name '
price of all the fruit whose name starts with the letter “a”.
$ jq '.[] | select(.name|test("^a.")) | .price' fruits.json
Use the map function to create a new array containing only colors. Then we pass each color in the new array to the unique function using a pipe |.
$ jq 'map(.color) | unique' fruits.json
[
"green",
"yellow"
]
to remove a key and corresponding value from JSON objects
$ jq 'del(.fruit.name)' fruit.json
# outputs the fruit object without the deleted key:
{
"fruit": {
"color": "green",
"price": 1.2
}
}
Object Identifier-Index jq '.key.subkey.subsubkey'
Consider this example document
{
"timestamp": 1234567890,
"report": "Age Report",
"results": [
{ "name": "John", "age": 43, "city": "TownA" },
{ "name": "Joe", "age": 10, "city": "TownB" }
]
}
jq '.[] | {timestamp,report}' # To extract top level attributes “timestamp” and “report”
jq '.results[] | {name, age}' # To extract name and age of each “results” item
# Filter this by attribute
jq '.results[] | select(.name == "John") | {age}' # Get age for 'John'
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'
Merging/overwriting keys
echo '{ "a": 1, "b": 2 }' |\
jq '. |= . + {
"c": 3
}'
Adding elements to lists
echo '{ "names": ["Marie", "Sophie"] }' |\
jq '.names |= .+ [
"Natalie"
]'
When you want to iterate and an array you access is empty you get something like
jq: error (at :3): Cannot iterate over null (null)
To workaround the optional array protect the access with
select(.my_array | length > 0)
From https://www.terraform.io/docs/providers/external/data_source.html
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)
To create proper JSON from a shell script and properly escape variables:
jq -n --arg foobaz "$FOOBAZ" '{"foobaz":$foobaz}'
-
--arg name value
:
This option passes a value to the jq program as a predefined variable. If you run jq with --arg foo bar, then $foo is available in the program and has the value "bar". Note that value will be treated as a string, so --arg foo 123 will bind $foo to "123".
Quick easy way to url encode something
date | jq -sRr @uri