JSON WalletPrivacy-first JSON & API workspace

A Practical jq Cookbook

9 min read

← All guides

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)'   # equivalent

Filter 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'   # descending

Flatten 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,true

The -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.ndjson

The -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

Ready to put this into practice? Open the free JSON editor β†’

Press ⌘ K for commands