jq#
jq is a streaming JSON processor. The operator reaches for it
the way they reach for awk on tab-separated text: a small
language that filters, selects, reshapes, and projects, with
predictable output the next pipeline stage can consume. jq
expects valid JSON in and (by default) produces valid JSON out.
Sample input#
The recipes below operate on this document. Save it as
buster.json to follow along.
{
"name": "Buster",
"breed": "Golden Retriever",
"age": 4,
"owner": { "name": "Sally" },
"likes": ["bones", "balls", "dog biscuits"]
}
Selecting#
$ jq . buster.json # pretty-print, no transform
$ jq .name buster.json # one top-level key
$ jq '.name, .age' buster.json # multiple, comma-separated
$ jq .owner.name buster.json # nested path
$ jq '.likes[0]' buster.json # array index
$ jq '.likes[0:2]' buster.json # array slice
$ jq '.likes | length' buster.json # length of an array
Filtering#
# On an array of objects, pull every name
$ jq '.[] | .name' pets.json
# Drop matches the operator doesn't want
$ jq '.[] | select(.age > 5)' pets.json
# Test for key presence
$ jq 'has("owner")' buster.json
Reshaping#
# Build a flat array from selected fields
$ jq '[.name, .likes[]]' buster.json
# Project to a new object shape
$ jq '{pet: .name, owner: .owner.name}' buster.json
# Delete keys the operator doesn't want downstream
$ jq 'del(.owner)' buster.json
Transforming#
# Map over an array, performing arithmetic
$ echo '[12, 14, 15]' | jq 'map(. - 2)' # [10, 12, 13]
# Increment a scalar by 1
$ echo '{"eggs":2}' | jq '.eggs + 1' # 3
# Convert JSON-lines back to a single array
$ jq -s . events.jsonl > events.json
# Convert a JSON array to JSON-lines for stream tools
$ jq -c '.[]' events.json > events.jsonl
References#
Python for when the projection outgrows
jqand the operator needs a real language.