Click any command to expand the explanation and examples.
🎯 Basics
. — identity / pretty print basics
# Pretty print JSON
echo '{"name":"Alice","age":30}' | jq .
From a file
jq . data.json
From curl
curl -s https://api.example.com/users | jq .
Compact output (one line)
jq -c . data.json
Raw strings (no quotes)
jq -r ‘.name’ data.json # Alice (not “Alice”)
.field — access fields basics
# Given: {"name": "Alice", "address": {"city": "Brussels"}}
jq ‘.name’ # “Alice”
jq ‘.address.city’ # “Brussels”
jq ‘.address’ # {“city”: “Brussels”}
Optional (no error if missing)
jq ‘.missing?’ # null
jq ‘.foo.bar?’ # null (no error)
📋 Arrays
.[] — iterate arrays array
# Given: [{"name":"Alice"},{"name":"Bob"},{"name":"Carol"}]
jq ’.[0]’ # {“name”:“Alice”}
jq ’.[-1]’ # {“name”:“Carol”} (last)
jq ’.[1:3]’ # Slice: items 1 and 2
jq ’.[]’ # Each item (one per line)
jq ’.[].name’ # “Alice” “Bob” “Carol”
jq ‘length’ # 3
Collect back into array
jq ’[.[].name]’ # [“Alice”,“Bob”,“Carol”]
map, select, sort array
# Given: [{"name":"Alice","age":30},{"name":"Bob","age":25}]
Map — transform each item
jq ‘map(.name)’ # [“Alice”,“Bob”]
jq ‘map({user: .name, years: .age})‘
Select — filter items
jq ‘map(select(.age > 25))’ # [{“name”:“Alice”,“age”:30}]
jq ’.[] | select(.name == “Bob”)’ # {“name”:“Bob”,“age”:25}
Sort
jq ‘sort_by(.age)’ # Sort by age ascending
jq ‘sort_by(.name) | reverse’ # Sort by name descending
Unique
jq ‘map(.role) | unique’
Group
jq ‘group_by(.role)‘
First / last
jq ‘first’
jq ‘last’
Length
jq ‘length’ # Array length
jq ’.[] | .name | length’ # String lengths
🔧 Transformations
Construct new objects transform
# Build new object
jq '{user: .name, mail: .email}'
From array items
jq ’.[] | {user: .name, mail: .email}‘
Collect into array
jq ’[.[] | {user: .name}]‘
Add/modify fields
jq ’. + {“active”: true}’
jq ‘.users[] | . + {“source”: “api”}‘
Delete a field
jq ‘del(.password)’
jq ‘map(del(.internal_id))‘
Rename a field
jq ’.[] | {username: .name, email}‘
String operations transform
# Concatenation jq '.first + " " + .last'String interpolation
jq ‘“Hello (.name), age (.age)“‘
Split / join
jq ‘.tags | join(”, ”)’ jq ‘.path | split(”/”)‘
Test (regex)
jq ‘select(.email | test(“@gmail”))‘
To/from number
jq ‘.count | tostring’ jq ‘.port | tonumber’
Upper/lower (jq 1.7+)
jq ‘.name | ascii_downcase’ jq ‘.name | ascii_upcase’
🔗 Pipes & Conditionals
Pipe and if/then/else logic
# Pipe (chain operations) jq '.users | map(.name) | sort'If/then/else
jq ‘.age | if . >= 18 then “adult” else “minor” end’
Alternative operator (default value)
jq ‘.nickname // .name’ # Use nickname, fallback to name jq ‘.port // 3000’ # Default port
Null check
jq ‘if .email then “has email” else “no email” end’
Try (ignore errors)
jq ‘try .foo.bar.baz’
📊 Aggregation
Count, sum, min, max aggregate
# Count jq 'length' # Array length jq 'map(select(.active)) | length' # Count where activeSum
jq ‘map(.price) | add’ jq ’[.[] | .quantity * .price] | add’
Min / max
jq ‘min_by(.age)’ jq ‘max_by(.score)’ jq ‘map(.price) | min’
Average
jq ‘map(.score) | add / length’
⚡ Common Patterns
Real-world one-liners pattern
# Pretty print API response curl -s https://api.github.com/users/octocat | jq .Extract specific fields from API
curl -s https://api.github.com/repos/user/repo/issues | jq ’.[] | {title, state, user: .user.login}‘
Convert JSON to CSV-ish
jq -r ’.[] | [.name, .email] | @csv’
Convert JSON to TSV
jq -r ’.[] | [.name, .email] | @tsv’
Flatten nested arrays
jq ‘flatten’
Merge objects
jq ’.[0] * .[1]’ # Deep merge
Read from multiple files
jq -s ’.’ file1.json file2.json # -s = slurp into array
Update a value in a file
jq ‘.version = “2.0.0”’ package.json > tmp && mv tmp package.json
Keys of an object
jq ‘keys’
Values of an object
jq ‘to_entries | map({key, value: .value})’