📋 Cheat Sheets

jq Cheat Sheet — Process JSON Like a Pro on the Command Line


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 active

Sum

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})’