jq is the standard command-line tool for slicing, filtering, and transforming JSON. It turns one-liners into a powerful query language for API responses, log files, and config. This tutorial covers installation, the core filters you'll use every day, and a set of copy-paste recipes for the most common real-world tasks.
What Is jq?
jq reads JSON from a file or standard input, applies a filter, and writes JSON (or raw text) to standard output. It pretty-prints by default and never sends your data anywhere — it's a local binary, ideal for sensitive payloads.
Installing jq
# macOS
brew install jq
# Debian / Ubuntu
sudo apt-get install jq
# Windows (winget or choco)
winget install jqlang.jq
# Verify
jq --versionThe Identity Filter: Pretty-Print Anything
The simplest filter, ., returns the input unchanged — which makes jq an instant formatter:
# Pretty-print a file
jq . data.json
# Pretty-print a curl response
curl -s https://api.example.com/users | jq .
# Minify instead (compact output)
jq -c . data.jsonSelecting Fields
Drill into objects with .key, and into arrays with []:
echo '{"user":{"name":"Ada","age":36}}' | jq '.user.name'
# "Ada"
# All elements of an array
echo '[{"id":1},{"id":2}]' | jq '.[]'
# {"id":1}
# {"id":2}
# One field from every array element
echo '[{"id":1,"name":"Ada"},{"id":2,"name":"Bob"}]' | jq '.[].name'
# "Ada"
# "Bob"
# Strip the JSON quotes with -r (raw output)
jq -r '.[].name' users.jsonFiltering with select
# Keep only objects matching a condition
echo '[{"name":"Ada","active":true},{"name":"Bob","active":false}]' \
| jq '.[] | select(.active == true)'
# {"name":"Ada","active":true}
# Numeric comparison
jq '.[] | select(.age > 30)' users.jsonTransforming with map and Object Construction
# Reshape every element into a new object
echo '[{"id":1,"name":"Ada","email":"a@x.com"}]' \
| jq 'map({ userId: .id, label: .name })'
# [{"userId":1,"label":"Ada"}]
# Pull a flat list of values
jq '[.[].email]' users.json # ["a@x.com", ...]
# Pipe filters together with |
jq '.items | map(.price) | add' order.json # sum of all pricesCommon Recipes
| Task | Command |
|---|---|
| Pretty-print | jq . file.json |
| Minify | jq -c . file.json |
| Get one field | jq '.data.token' resp.json |
| Raw string (no quotes) | jq -r '.token' resp.json |
| Count array items | jq '. | length' list.json |
| Keys of an object | jq 'keys' obj.json |
| Filter rows | jq '.[] | select(.active)' |
| Sort by a field | jq 'sort_by(.age)' |
| Sum a field | jq '[.[].amount] | add' |
| Sort object keys | jq --sort-keys . file.json |
| Validate (exit code) | jq empty file.json |
Reshaping Objects: to_entries / from_entries
The two most useful object-shape transformers in jq:
# Rename every key (lowercase here)
echo '{"Name":"Ada","Active":true}' \
| jq 'with_entries(.key |= ascii_downcase)'
# → {"name":"Ada","active":true}
# Drop keys whose value is null
jq 'with_entries(select(.value != null))' file.json
# Object ⇄ array of pairs
jq 'to_entries' file.json # → [{"key":"name","value":"Ada"}, ...]
jq 'from_entries' pairs.json # → {"name":"Ada", ...}Interpolation and Output Formats: \(.x), @csv, @json, @base64
jq has string interpolation and built-in format strings for turning JSON into other formats:
# String interpolation inside a quoted string
jq -r '"\(.user) bought \(.items|length) items"' order.json
# CSV row per object
jq -r '.[] | [.id, .name, .total] | @csv' orders.json
# Inline-JSON for shells (escaped string literal)
jq -r '.user | @json' record.json
# Base64-encode a value (handy for tokens / data URIs)
jq -r '.payload | @base64' message.json
# Decode side: jq accepts @base64d in newer versionsValidating JSON with jq
Because jq exits non-zero on invalid input, jq empty file.json is a clean validity check for scripts and CI — see How to Validate JSON for more validation approaches.
When a Browser Tool Is Faster
jq shines in scripts and pipelines, but for a quick one-off — pretty-printing a pasted response, inspecting an unfamiliar structure, or repairing broken JSON — a browser tool needs no installation and no shell escaping:
- JSON Fix — format and repair JSON in one step
- JSON Viewer — explore large responses as a collapsible tree
- How to Format JSON — formatting in code and on the command line
Frequently Asked Questions
How do I pretty-print JSON with jq?
Run jq . file.json — the identity filter . returns the input and jq formats it by default. Use -c for compact output instead.
How do I extract a single field with jq?
Use a path filter like jq '.data.token', and add -r for raw output if you want the value without surrounding quotes.
How do I filter a JSON array with jq?
Iterate with .[] and apply select(), e.g. jq '.[] | select(.active == true)'.
Can jq validate JSON?
Yes — jq empty file.json parses the input and exits non-zero if it's invalid, making it handy in CI. For details see How to Validate JSON.
Keep Going
- How to Format JSON — jq, JavaScript, Python, and browser formatting
- How to Minify JSON — compact output with
jq -cand beyond - How to Validate JSON — including
jq emptyin CI - JSON Viewer — a browser alternative for exploring JSON