jq Cheat Sheet

A complete quick-reference for jq — the command-line JSON processor. Search by keyword or filter by category to find the exact operator, builtin, or flag you need.

🔧 About jq

jq is a lightweight, flexible command-line JSON processor created by Stephen Dolan in 2012. Think of it as sed/awk for JSON — a small functional language for slicing, filtering, mapping, and reshaping structured data in shell pipelines. It is the de-facto standard tool for working with JSON in scripts, CI, and one-off ops tasks.

Key Characteristics

  • Stream-based: Filters emit 0, 1, or many values
  • Composable: Pipes (|) chain filters together
  • Single binary: No runtime or dependencies
  • Tiny syntax: A page of operators covers most needs
  • Battle-tested: Stable since 2012, ubiquitous in DevOps
  • MIT licensed: Free for any use

Common Use Cases

  • Extract fields from REST / GraphQL responses
  • Filter logs and Kubernetes manifests
  • Reshape JSON for CSV / TSV import
  • Build CI pipelines that read structured output
  • Diff & sort JSON for review
  • Generate JSON test fixtures on the fly

Mental Model

Every jq filter takes one JSON value as input and emits a stream of zero or more JSON values as output. . is the identity filter. .foo projects a field. .[] iterates. The pipe | feeds the output of one filter into the next. Almost everything in jq is built from those four ideas.

76 entries found
Filter:

.

Basics

Identity filter — emits the input unchanged. Often used to pretty-print JSON.

Syntax:

jq .

Examples:

echo '{"a":1,"b":2}' | jq .
Pretty-print JSON
curl -s https://api.example.com/data | jq .
Format an API response

Notes:

jq pretty-prints by default. Use -c (compact) to keep it on one line.

.foo

Basics

Object field access — emits the value of key "foo".

Syntax:

jq '.field'

Examples:

echo '{"name":"Ada"}' | jq '.name'
Get a top-level field
jq '.user.address.city' data.json
Chain field accesses

Notes:

Field names that aren't valid identifiers need quoting: .["weird-key"].

.foo?

Basics

Optional access — yields nothing instead of erroring when input is not an object.

Syntax:

jq '.field?'

Examples:

echo '[1,2,3]' | jq '.foo?'
No error on type mismatch
jq '.. | .price?'
Walk anywhere, collect prices, ignore non-objects

Notes:

Use ? whenever a filter may encounter mixed types.

.[n]

Basics

Array index — negative indices count from the end.

Syntax:

jq '.[INDEX]'

Examples:

echo '[10,20,30]' | jq '.[0]'
First element → 10
jq '.[-1]' items.json
Last element

.[a:b]

Basics

Array / string slice — half-open range [a, b).

Syntax:

jq '.[START:END]'

Examples:

echo '[1,2,3,4,5]' | jq '.[1:3]'
Returns [2,3]
echo '"hello"' | jq '.[1:4]'
Returns "ell"

Notes:

Either bound may be omitted: .[:3] or .[2:].

.[]

Basics

Iterate — emits each array element or object value as a separate output.

Syntax:

jq '.[]'

Examples:

jq '.users[]' data.json
Stream each user object
jq '.users[] | .email'
Pipe each user into another filter

Notes:

Wrap in [...] to collect the stream back into an array.

..

Basics

Recursive descent — every value at every depth, in DFS order.

Syntax:

jq '..'

Examples:

jq '.. | numbers' data.json
Every number anywhere in the doc
jq '.. | .id? | select(. != null)'
Every id field, ignoring misses

|

Pipes & Composition

Pipe — feed output of one filter as input to the next.

Syntax:

F1 | F2

Examples:

jq '.users[] | .name'
Iterate users, project the name
jq '.orders | length' data.json
Count orders

,

Pipes & Composition

Comma — emit the outputs of each filter, in order.

Syntax:

F1, F2

Examples:

jq '.name, .email' user.json
Emit both fields, two values
jq '.first, .last' names.json
Stream two fields per object

( ... )

Pipes & Composition

Group filters — parentheses override default precedence.

Syntax:

(F1, F2) | F3

Examples:

jq '(.a, .b) | tostring'
Stringify both a and b
jq '(.x // 0) + 1'
Increment x with default 0

//

Pipes & Composition

Alternative — return left side if defined and non-null, else right side.

Syntax:

EXPR // DEFAULT

Examples:

jq '.name // "anonymous"' user.json
Provide a default value
jq '.config.port // 8080'
Default port for missing config

|=

Pipes & Composition

Update-assignment — apply a filter to the value at a path.

Syntax:

PATH |= EXPR

Examples:

jq '.price |= . * 1.1' product.json
Raise price by 10%
jq '.tags |= map(ascii_downcase)'
Lowercase every tag

Notes:

Related: = (set), += (add), -= (subtract), //= (default-if-null).

select(f)

Filtering

Pass-through if f is truthy — discard otherwise.

Syntax:

select(CONDITION)

Examples:

jq '.[] | select(.price < 20)'
Items cheaper than 20
jq '.[] | select(.tags | contains(["sale"]))'
Items with the "sale" tag

if-then-elif-else-end

Filtering

Conditional — emit different filters based on a predicate.

Syntax:

if COND then A elif COND2 then B else C end

Examples:

jq 'if .age < 18 then "minor" else "adult" end'
Map ages to a label
jq 'if .status == "ok" then .data else error("bad") end'
Branch on status

Notes:

else is optional — without it, the input is passed through unchanged.

has(k)

Filtering

True if input has key k (object) or index k (array).

Syntax:

has(KEY)

Examples:

jq '.[] | select(has("email"))'
Keep items that have an email field
jq 'has(2)' '[1,2,3]'
True — index 2 exists

contains(v)

Filtering

Recursive containment — true if input contains v structurally.

Syntax:

contains(VALUE)

Examples:

jq '. | contains({user: {name: "Ada"}})'
Nested object match
jq '.tags | contains(["sale"])'
Array contains the substring

Notes:

Strings: substring match. Arrays: every element of b matches some element of a.

in(o)

Filtering

True if input is a key in object o (or an index in array o).

Syntax:

in(OBJECT)

Examples:

jq '"name" | in({name: 1, age: 2})'
True — "name" is a key
jq '.[] | select(.id | in($whitelist))'
Filter by allowed ids

not

Filtering

Logical negation — postfix, applied via pipe.

Syntax:

EXPR | not

Examples:

jq '.[] | select(.archived | not)'
Only un-archived rows
jq 'false | not'
Returns true

arrays, objects, strings, numbers, booleans, nulls, iterables, scalars

Filtering

Type-picker filters — pass the input only if it has the matching type.

Syntax:

arrays | objects | strings | ...

Examples:

jq '.. | strings'
Every string anywhere in the doc
jq '.. | objects | select(.id?)'
Objects that have an id

length

Array & Object Operations

Length of array, string, or object; absolute value of a number; 0 for null.

Syntax:

length

Examples:

jq '.items | length'
Count of items
jq '.name | length' user.json
Length of a string

keys / keys_unsorted

Array & Object Operations

Sorted keys of an object (or 0..n-1 for arrays). keys_unsorted preserves order.

Syntax:

keys

Examples:

jq '.user | keys'
List the user object's fields
jq 'keys_unsorted' map.json
Keep insertion order

values

Array & Object Operations

Array of values from an object (or the array itself).

Syntax:

values

Examples:

jq '.counts | values | add'
Sum every value in the object
jq '.users | values | length'
Count entries

map(f)

Array & Object Operations

Apply f to every element of an input array — shorthand for [.[] | f].

Syntax:

map(EXPR)

Examples:

jq '.prices | map(. * 1.2)'
Raise every price by 20%
jq '.users | map(.email)'
Extract all emails

map_values(f)

Array & Object Operations

Apply f to every value of an object (or array element) — keeps keys.

Syntax:

map_values(EXPR)

Examples:

jq '.counts | map_values(. + 1)'
Increment every value
jq '.users | map_values(.name)'
Replace each user with their name

to_entries

Array & Object Operations

Convert {k: v} → [{key: k, value: v}, ...] — enables iterating with keys.

Syntax:

to_entries

Examples:

jq '. | to_entries' '{"a":1,"b":2}'
Yields [{key:"a",value:1},...]
jq 'to_entries | map(.key)'
Same as `keys_unsorted`

from_entries

Array & Object Operations

Inverse of to_entries — array of {key, value} → object.

Syntax:

from_entries

Examples:

jq '[{key:"a",value:1},{key:"b",value:2}] | from_entries'
Yields {a:1,b:2}
jq 'to_entries | map(select(.value > 0)) | from_entries'
Drop zero-valued keys

with_entries(f)

Array & Object Operations

Shorthand for to_entries | map(f) | from_entries — rewrite an object.

Syntax:

with_entries(EXPR)

Examples:

jq 'with_entries(.key |= ascii_downcase)'
Lowercase every key
jq 'with_entries(select(.value != null))'
Drop null fields

{ k: v, ... }

Array & Object Operations

Object construction — { name, age } uses .name as both key and value.

Syntax:

{ field, key: EXPR, "literal-key": EXPR }

Examples:

jq '{name, email}'
Project two fields
jq '{id, total: (.qty * .price)}'
Compute a derived field

[ ... ]

Array & Object Operations

Array construction — collect a filter's outputs into an array.

Syntax:

[ EXPR ]

Examples:

jq '[.users[].name]'
All names as one array
jq '[range(5)]'
Build [0,1,2,3,4]

sort, sort_by(f)

Sorting & Aggregation

Sort an array. sort_by uses f as the comparison key.

Syntax:

sort | sort_by(EXPR)

Examples:

jq '[3,1,4,1,5] | sort'
Yields [1,1,3,4,5]
jq '.books | sort_by(.price)'
Cheapest first
jq '.books | sort_by(-.rating)'
Descending by rating

group_by(f)

Sorting & Aggregation

Group consecutive equal-key items — input is sorted by f first.

Syntax:

group_by(EXPR)

Examples:

jq '.orders | group_by(.status)'
Group orders by status
jq '.events | group_by(.day) | map({day: .[0].day, count: length})'
Count events per day

unique, unique_by(f)

Sorting & Aggregation

Sort + dedupe an array. unique_by uses f as the key.

Syntax:

unique | unique_by(EXPR)

Examples:

jq '[1,2,2,3,3,3] | unique'
Yields [1,2,3]
jq '.users | unique_by(.email)'
Dedupe by email

min, max, min_by(f), max_by(f)

Sorting & Aggregation

Smallest/largest element of an array; min_by/max_by use f as the key.

Syntax:

min | max | min_by(EXPR) | max_by(EXPR)

Examples:

jq '[5,1,9,3] | max'
Returns 9
jq '.products | max_by(.price)'
Most expensive product

add

Sorting & Aggregation

Add all elements of an array — numbers sum, strings/arrays concatenate, objects merge.

Syntax:

add

Examples:

jq '[.orders[].qty] | add'
Total quantity across orders
jq '[{a:1},{b:2}] | add'
Yields {"a":1,"b":2} — object merge
jq '["foo","bar"] | add'
Yields "foobar"

any, all, any(f), all(f)

Sorting & Aggregation

Boolean reductions over an array — short-circuit semantics.

Syntax:

any | all | any(EXPR) | all(EXPR)

Examples:

jq '.users | all(.active)'
All users currently active?
jq '.orders | any(.status == "failed")'
Any failed order?

first, last, nth(n; f)

Sorting & Aggregation

Extract first / last / nth element of an array or filter output.

Syntax:

first | last | nth(N; EXPR)

Examples:

jq '.results | first'
First result
jq 'nth(2; .users[])'
Third user from the stream

reverse

Sorting & Aggregation

Reverse the order of an array or string.

Syntax:

reverse

Examples:

jq '[1,2,3] | reverse'
Yields [3,2,1]
jq '.events | sort_by(.ts) | reverse'
Newest first

range(n) / range(a; b) / range(a; b; step)

Sorting & Aggregation

Generate an integer stream.

Syntax:

range(N) | range(A; B) | range(A; B; STEP)

Examples:

jq -n '[range(5)]'
Yields [0,1,2,3,4]
jq -n '[range(0; 10; 2)]'
Yields [0,2,4,6,8]

Notes:

Combine with -n (null input) when generating data.

"\( ... )"

Strings & Regex

String interpolation — embed any jq expression inside a string literal.

Syntax:

"prefix \(EXPR) suffix"

Examples:

jq '"Hello, \(.name)!"' user.json
Greeting from field
jq '"User #\(.id): \(.email)"'
Compose a log line

split(s), join(s)

Strings & Regex

Split string on separator → array. Join array → string.

Syntax:

split(SEP) | join(SEP)

Examples:

jq '"a,b,c" | split(",")'
Yields ["a","b","c"]
jq '.tags | join(", ")'
CSV-style tag string

ascii_downcase, ascii_upcase

Strings & Regex

Lower-case / upper-case an ASCII string.

Syntax:

ascii_downcase | ascii_upcase

Examples:

jq '.email | ascii_downcase'
Normalize an email
jq '.code | ascii_upcase'
Country code in upper case

ltrimstr(s), rtrimstr(s)

Strings & Regex

Strip a fixed prefix / suffix if present.

Syntax:

ltrimstr(S) | rtrimstr(S)

Examples:

jq '.url | ltrimstr("https://")'
Drop the scheme
jq '.file | rtrimstr(".json")'
Drop a known extension

startswith(s), endswith(s)

Strings & Regex

Prefix / suffix predicates.

Syntax:

startswith(S) | endswith(S)

Examples:

jq '.[] | select(.name | startswith("test_"))'
Keep test entries
jq '.files | map(select(endswith(".log")))'
Filter for log files

test(re), match(re)

Strings & Regex

Regex predicates. test → bool, match → capture object.

Syntax:

test(PATTERN) | match(PATTERN)

Examples:

jq '.[] | select(.email | test("@gmail\\.com$"))'
Gmail addresses
jq '.title | match("(\\d+)")'
First number in the title with offset/length

Notes:

jq uses Oniguruma regex (PCRE-like). Escape backslashes for the shell.

sub(re; s), gsub(re; s)

Strings & Regex

Replace first / all regex matches.

Syntax:

sub(PATTERN; REPLACEMENT) | gsub(PATTERN; REPLACEMENT)

Examples:

jq '.msg | gsub("\\s+"; "_")'
Whitespace to underscores
jq '.path | sub("^/api/"; "/v2/")'
Rewrite a prefix

tostring, tonumber

Strings & Regex

Convert between string and number representations.

Syntax:

tostring | tonumber

Examples:

jq '.[] | .id | tostring'
Stringify ids for keys
jq '"42" | tonumber'
Parse number from string

@csv, @tsv

Format Strings

Format an array of scalars as a CSV / TSV row.

Syntax:

[F1, F2, ...] | @csv

Examples:

jq -r '[.id, .name, .price] | @csv'
Build a CSV row
jq -r '.users[] | [.id, .email] | @tsv'
Stream users as TSV — use -r for raw output

Notes:

Always combine format strings with -r so quotes are not re-escaped.

@json

Format Strings

Re-encode the input value as a JSON string literal.

Syntax:

. | @json

Examples:

jq '@json' '{"a":1}'
Yields the string "{\"a\":1}"
jq -r '.items[] | @json'
One JSON document per line (NDJSON)

@uri

Format Strings

URI-encode the input — safe for use in URLs.

Syntax:

. | @uri

Examples:

jq -r '"https://example.com/?q=\(.query | @uri)"'
Build a safe query URL

@base64, @base64d

Format Strings

Base64 encode / decode the input string.

Syntax:

. | @base64 | @base64d

Examples:

jq -r '.token | @base64'
Base64-encode a value
jq -r '.encoded | @base64d'
Decode a base64 string

@sh

Format Strings

Shell-quote a value (or array of values) for safe interpolation in a shell command.

Syntax:

. | @sh

Examples:

jq -r '.files | @sh' | xargs rm
Safely delete a list of files

Notes:

Single-quotes everything — even values containing spaces or quotes.

+ - * / %

Math

Arithmetic on numbers — also: + concatenates arrays/strings/objects.

Syntax:

A + B | A - B | A * B | A / B | A % B

Examples:

jq '.price * 1.1'
Raise price 10%
jq '.a + .b' '{"a":[1],"b":[2]}'
Concat arrays → [1,2]
jq '.first + " " + .last'
Concat strings

floor, ceil, round, fabs/abs, sqrt

Math

Standard math functions on numbers.

Syntax:

floor | ceil | round | fabs | sqrt

Examples:

jq '3.7 | floor'
Returns 3
jq '.amount | round'
Round to nearest integer

== != < <= > >=

Math

Equality and ordered comparisons — work on any JSON value (jq compares structurally).

Syntax:

A == B | A < B | A >= B

Examples:

jq '.[] | select(.price < 50)'
Filter by number
jq '.[] | select(.tags == ["sale","new"])'
Array-equality check

paths, paths(f), leaf_paths

Paths & Recursion

Emit every path (array of keys/indices) in the document. leaf_paths skips containers.

Syntax:

paths | paths(EXPR) | leaf_paths

Examples:

jq '[paths]'
List every path in the doc
jq '[paths(type == "number")]'
Paths to every numeric value

getpath(p)

Paths & Recursion

Read the value at path p (where p is an array like ["a", 0, "b"]).

Syntax:

getpath(PATH)

Examples:

jq 'getpath(["user","name"])'
Same as .user.name
jq 'paths as $p | getpath($p) | numbers'
All numbers, via paths

setpath(p; v)

Paths & Recursion

Set the value at path p — useful with calculated paths.

Syntax:

setpath(PATH; VALUE)

Examples:

jq 'setpath(["user","email"]; "x@y.com")'
Overwrite a nested field

recurse, recurse(f)

Paths & Recursion

Apply f repeatedly, emitting each output (default: walk children).

Syntax:

recurse | recurse(EXPR)

Examples:

jq 'recurse'
Every node, depth-first
jq 'recurse(.children[]?) | .name'
Walk a tree of children, emit names

walk(f)

Paths & Recursion

Bottom-up traversal — apply f to every value after its children are visited.

Syntax:

walk(EXPR)

Examples:

jq 'walk(if type == "string" then ascii_downcase else . end)'
Lowercase every string anywhere in the doc

as $name | ...

Variables & Errors

Bind the output of a filter to a variable, then continue.

Syntax:

EXPR as $NAME | BODY

Examples:

jq '.users[] as $u | $u.email'
Iterate users, bind each
jq '. as $root | .items[] | {name, root: $root.name}'
Keep a reference to the outer object

try / catch

Variables & Errors

Run a filter; swallow or transform errors.

Syntax:

try EXPR catch HANDLER

Examples:

jq 'try .a.b.c catch "missing"'
Default value on error
jq 'try (.items | length) catch 0'
Count, or 0 on error

error(msg)

Variables & Errors

Raise an error — terminate the current filter unless caught.

Syntax:

error("MESSAGE")

Examples:

jq 'if .status == "ok" then .data else error("bad status: \(.status)") end'
Fail noisily on bad data

reduce EXPR as $x (INIT; UPDATE)

Variables & Errors

Fold over a stream — like reduce/fold in other languages.

Syntax:

reduce EXPR as $x (INIT; UPDATE)

Examples:

jq 'reduce .[] as $x (0; . + $x)' '[1,2,3,4]'
Sum (returns 10) — same as add
jq 'reduce .users[] as $u ({}; .[$u.email] = $u)'
Index users by email

foreach EXPR as $x (INIT; UPDATE; EXTRACT)

Variables & Errors

Like reduce, but emits the EXTRACT result on every iteration.

Syntax:

foreach EXPR as $x (INIT; UPDATE; EXTRACT)

Examples:

jq 'foreach .[] as $x (0; . + $x; .)' '[1,2,3]'
Running sum: 1, 3, 6

def name(args): body;

Variables & Errors

Define a reusable user function inside a jq program.

Syntax:

def NAME($p1; $p2): BODY;

Examples:

jq 'def double(x): x * 2; .price | double(.)'
Define and use a helper

tojson, fromjson

Misc & I/O

Serialize value to a JSON string / parse a JSON string back into a value.

Syntax:

tojson | fromjson

Examples:

jq '.config | tojson'
Stash a value as a string
jq '.encoded | fromjson | .data'
Parse JSON inside a string field

$ENV / env

Misc & I/O

Access shell environment variables from inside a jq filter.

Syntax:

$ENV.NAME | env.NAME

Examples:

jq -n '{user: $ENV.USER}'
Inject env var into JSON

input, inputs

Misc & I/O

Consume the next input(s) from the stream — useful with -n.

Syntax:

input | inputs

Examples:

jq -n '[inputs] | length' a.json b.json
Count how many top-level JSON values

empty

Misc & I/O

Emit no values — useful inside conditionals to drop an output.

Syntax:

empty

Examples:

jq '.[] | if .ok then . else empty end'
Drop rows where .ok is false

-r (raw output)

CLI Flags

Print string outputs without JSON quotes — needed for shell piping.

Syntax:

jq -r FILTER

Examples:

jq -r '.users[].email' data.json
One email per line, unquoted
jq -r '.files[]' | xargs ls -l
Pipe filenames into another tool

-c (compact output)

CLI Flags

Print each JSON value on a single line — ideal for NDJSON / JSONL.

Syntax:

jq -c FILTER

Examples:

jq -c '.[]' big.json > stream.ndjson
Convert array → NDJSON file

-s (slurp)

CLI Flags

Read all inputs into a single array before applying the filter.

Syntax:

jq -s FILTER

Examples:

jq -s 'add' a.json b.json
Merge multiple JSON arrays
jq -s 'length' stream.ndjson
Count lines in an NDJSON file

-n (null input)

CLI Flags

Don't read input — start with null. Used with generators like range or env.

Syntax:

jq -n FILTER

Examples:

jq -n '[range(5)]'
Generate [0,1,2,3,4] from nothing
jq -n '$ENV.HOME'
Echo an env var as JSON

--arg / --argjson

CLI Flags

Bind a string ( --arg ) or JSON ( --argjson ) value to a variable in your filter.

Syntax:

--arg NAME VALUE | --argjson NAME JSON

Examples:

jq --arg q "ada" '.users[] | select(.name == $q)'
Pass shell variable into jq
jq --argjson ids '[1,2,3]' '.[] | select(.id | IN($ids[]))'
Pass a JSON array as a filter

-S (sort keys)

CLI Flags

Sort object keys alphabetically in the output — produces canonical JSON.

Syntax:

jq -S FILTER

Examples:

jq -S . data.json
Pretty-print with sorted keys (diff-friendly)

--slurpfile / --rawfile

CLI Flags

Read a JSON file (or raw text file) into a variable for use in the filter.

Syntax:

--slurpfile NAME FILE | --rawfile NAME FILE

Examples:

jq --slurpfile cfg config.json '. + $cfg[0]' data.json
Merge an external config
jq --rawfile readme README.md '{readme: $readme}'
Embed a text file as a JSON string

How to Use the jq Cheat Sheet

  1. Use the search box above to find an operator, builtin, or flag by name (e.g. select, group_by, -r). Searches match the command, description, syntax, and every example.
  2. Use the category chips to narrow down by area — Basics, Filtering, Sorting & Aggregation, Strings & Regex, Paths & Recursion, CLI Flags, and more.
  3. Each card shows the syntax skeleton and one or more runnable examples with a short description of what each one does.
  4. Copy any example, paste it into your terminal (with real input), and tweak. Pair this page with the jq Query Tester to iterate filters live in the browser before deploying them.
  5. Read the Notes section under each card for gotchas — escaping, shell interpolation, and feature flags.

Common Use Cases

API Response Inspection

  • Pretty-print: curl ... | jq .
  • Extract a single field: jq -r '.token'
  • Stream items: jq '.items[]'

Filtering & Reshaping

  • Drop rows: map(select(.active))
  • Project fields: map({id, name})
  • Rename keys: with_entries(.key |= ascii_downcase)

CSV / TSV Export

  • CSV row: [.id, .name] | @csv
  • Bulk export: jq -r '.[] | [.a,.b] | @csv'
  • TSV for spreadsheets: @tsv

Aggregations

  • Count: length
  • Sum: [.[] | .qty] | add
  • Group: group_by(.status)

CI & DevOps

  • Read kubectl output: kubectl get pods -o json | jq
  • Read terraform state: terraform show -json | jq
  • Build dynamic JSON: jq -n --arg v "$X" '{val: $v}'

Validation

  • Type check: type == "number"
  • Required fields: all(has("id"))
  • Fail loudly: if bad then error("…") else . end

Frequently Asked Questions

What does | do in jq?

The pipe sends the output of the filter on the left as the input of the filter on the right. .users[] | .email iterates each user and projects the email — exactly like a shell pipe, but for JSON values.

Why does my filter return multiple lines?

jq filters are streams: a single filter can emit zero, one, or many JSON values. .items[] emits each item separately. Wrap it in [ ... ] to collect the stream back into one array.

How do I get raw strings without quotes?

Use the -r flag: jq -r '.users[].email' prints each email on its own line with no quoting — ideal for piping into xargs or shell loops.

What's the difference between .foo and .foo??

Both project a field. .foo raises an error when the input is not an object; .foo? swallows the error and emits nothing. Use the optional form when iterating heterogeneous data.

How do I filter array items by a condition?

Combine .[] with select(...): .orders[] | select(.status == "shipped") emits only the shipped orders. Wrap in [...] to keep them as one array.

How do I pass a shell variable into jq?

Don't interpolate it into the jq program — use --arg (string) or --argjson (JSON): jq --arg q "$USER" '.users[] | select(.name == $q)'. Safer and handles quoting for you.

How do I merge two JSON files?

Read both into one array with -s (slurp), then add them: jq -s '.[0] * .[1]' a.json b.json. The * operator does deep merge for objects; + does shallow merge.

Why are my regex backslashes being eaten?

The shell consumes one layer of backslashes before jq sees the program. To match a literal digit (regex \d) inside a jq filter, use '\\d' in single-quoted shell strings, or "\\\\d" when double-quoted.

Where can I try filters without leaving the browser?

Use the jq Query Tester — paste any JSON, write a filter, and see live results without installing anything.

Want to try jq filters in your browser?

Paste any JSON, write a jq expression, and preview the transformed output instantly — 100% client-side with sample queries and inline errors.

jq Query Tester →