jq Common Commands - CodeSwordsman

Practical jq recipes for reading, filtering, reshaping, aggregating and converting JSON from APIs and logs.

jq 1.6+Updated 2026-10-2930 commands

Access & Pipes

Pretty-print the entire JSON document

jq '.' data.json

Read a field from a nested object

jq '.user.name' data.json

Read a field from the first array element

jq '.items[0].id' data.json

Expand an array into separate outputs

jq '.items[]' data.json

Fall back to a default when the field is missing or null

jq '.user.name // "unknown"' data.json

Filter & Map

Keep only elements matching a condition

jq '.[] | select(.age > 18)' users.json

Map each element to a single field

jq 'map(.name)' users.json

Count elements matching a condition

jq '[.[] | select(.active)] | length' users.json

Filter elements then project one field

jq '.[] | select(.role == "admin") | .email' users.json

Keep elements whose array field contains a value

jq '.[] | select(.tags | index("vue"))' posts.json

Build & Delete

Build a new object with selected fields

jq '{name: .user.name, city: .user.city}' data.json

Remove sensitive fields from the output

jq 'del(.password, .token)' user.json

Reshape array elements with shorthand field picks

jq '.items | map({id, price})' data.json

Merge extra fields into an object

jq '. + {env: "prod"}' data.json

Filter object fields by key name

jq 'to_entries | map(select(.key != "password")) | from_entries' user.json

Sort, Group & Aggregate

Sort elements by a field in ascending order

jq 'sort_by(.price)' products.json

Sort by a numeric field in descending order

jq 'sort_by(-.price)' products.json

Group elements by a field and count members

jq 'group_by(.category) | map({category: .[0].category, count: length})' products.json

Sum a numeric field across all elements

jq '[.[].price] | add' products.json

Deduplicate by a field, keeping the first occurrence

jq 'unique_by(.email)' users.json

Format & Output

Drop string quotes for shell-friendly output

jq -r '.items[].name' data.json

-r affects strings only; numbers are printed unquoted anyway

Compact output on one line for logs and pipes

jq -c '.' data.json

Emit CSV rows ready for spreadsheets

jq -r '.[] | [.id, .name] | @csv' users.json

Emit tab-separated rows

jq -r '.[] | [.id, .name] | @tsv' users.json

Pass a shell variable into the jq filter

jq --arg env "prod" '.env = $env' data.json

Real-World Recipes

Merge multiple JSON arrays into one

jq -s 'add' a.json b.json

-s slurps all inputs into a single array

Filter error lines out of a JSONL log

jq -c 'select(.level == "error")' app.log

Each line must be a complete JSON value

Generate JSON from a shell variable and the current time

jq -n --arg v "$(git rev-parse --short HEAD)" '{"version": $v, "builtAt": (now | todate)}' > meta.json

Recursively collect id fields anywhere in the tree

jq '.. | objects | select(has("id")) | .id' data.json

Flatten nested JSON into dot-separated keys

jq 'reduce paths(scalars) as $p ({}; .[($p | join("."))] = getpath($p))' data.json

Related tools

This website uses cookies to ensure you get the best experience on our website. Privacy Policy.