A Practical jq Cookbook
9 min read
jq is the standard tool for slicing JSON on the command line, but its syntax takes a while to click. This cookbook skips the theory and gives you working recipes for the tasks that come up most often. Try any of them live, without installing anything, in the jq playground.
The sample data
{
"users": [
{ "name": "Ada", "active": true, "age": 36, "roles": ["admin"] },
{ "name": "Grace", "active": false, "age": 41, "roles": ["dev"] },
{ "name": "Linus", "active": true, "age": 29, "roles": ["dev", "admin"] }
]
}Select a field from every element
jq '.users[].name'
# "Ada"
# "Grace"
# "Linus"Collect values into an array
jq '[.users[].name]'
# ["Ada", "Grace", "Linus"]
jq '.users | map(.name)' # equivalentFilter with select
# only active users
jq '.users[] | select(.active)'
# users over 30, names only
jq '.users[] | select(.age > 30) | .name'Reshape each object
jq '.users | map({ name, isActive: .active })'
# [{ "name": "Ada", "isActive": true }, ...]Count, sum and average
jq '.users | length' # 3
jq '[.users[].age] | add' # 106
jq '[.users[].age] | add / length' # 35.3...Group by a field
jq '.users | group_by(.active)
| map({ active: .[0].active, count: length })'
# [{ "active": false, "count": 1 }, { "active": true, "count": 2 }]Sort
jq '.users | sort_by(.age)' # ascending by age
jq '.users | sort_by(.age) | reverse' # descendingFlatten and deduplicate
# every distinct role across all users
jq '[.users[].roles[]] | unique'
# ["admin", "dev"]Convert JSON to CSV
jq -r '.users[] | [.name, .age, .active] | @csv'
# "Ada",36,true
# "Grace",41,false
# "Linus",29,trueThe -r flag prints raw output, and @csv handles the quoting. For a point-and-click version, see JSON to CSV.
Turn a big array into NDJSON
jq -c '.users[]' data.json > users.ndjsonThe -c flag puts each result on one compact line β perfect for streaming large files, as covered in working with large JSON files.
Frequently asked questions
What is the difference between .users[] and [.users[]]?
.users[] streams each element as a separate output; wrapping it in [ ] collects those outputs back into a single array. Use the stream form for piping into select or map, and the array form when you need one array result.
Why does my filter error with 'Cannot index array with string'?
You applied an object accessor like .name to an array. Add [] to iterate the array first: .users[].name, not .users.name.
Can I test these without installing jq?
Yes. The jq playground runs the real jq engine in your browser, so every recipe here works there unchanged.
Related
For a selection-only query language, see querying JSON with JSONPath; for declarative transformations, read transforming JSON with JSONata.
Primary references
This guide is checked against the specifications and runtime documentation below. Examples are also run through JSON Wallet before publication.
Keep reading
What Is JSON? A Beginnerβs Guide
JSON is the most widely used data format on the web. This guide explains what it is, how it is structured, and where you will run into it as a developer.
JSON Syntax Rules Explained (With Examples)
JSON has a small but strict grammar. This reference walks through every rule with valid and invalid examples so your data parses the first time.
Common JSON Errors and How to Fix Them
Every developer hits "Unexpected token in JSON" eventually. Here are the most common JSON errors, what causes them, and exactly how to fix each one.
Ready to put this into practice? Open the free JSON editor β