Every entry below is a jq filter, what it returns, and a minimal example. Output shown came from jq 1.8.2.

For the guided version with explanations and larger worked examples, read the jq Cookbook.

Run Any Entry Here

The runner holds the same employees.json used throughout this reference. Paste any filter from the entries below into the filter box and press Run.

Press Run to execute this filter.

Selecting Values

The identity filter and field access. These cover most single-value lookups.

  • . returns the whole input unchanged. Use it to pretty-print.
  • .company returns one field. Returns null when the key is absent.
  • ."odd key" returns a field whose name contains spaces or punctuation.
  • .a.b.c walks nested objects. Any missing level yields null.
  • .a? suppresses the error when the input is not an object.
  • .employees[] emits each array element as a separate result.
  • .employees[0] returns one element by index. Indexes start at 0.
  • .employees[-1] counts from the end.
  • .employees[1:3] slices from index 1 up to but excluding index 3.
  • .. recurses through every value in the document.
jq -r '.employees[0].name' employees.json
Ada Lopez

Filtering With select

select(condition) passes an input through when the condition is true and emits nothing when it is false.

  • select(.age > 30) keeps matching values.
  • select(.dept == "Design") compares for equality.
  • select(.age > 30 and .dept == "Engineering") combines with and, or, and not.
  • select(.name | test("^[ab]"; "i")) matches a regular expression. The second argument holds flags, where i means case-insensitive.
  • select(.skills | index("go")) keeps values whose array contains a member.
  • select(.manager == null) finds explicit nulls.
  • select(has("email")) tests for a key rather than a value.

not is a filter, so it follows a pipe rather than preceding the expression.

jq -r '.employees[] | select(.age > 30) | .name' employees.json
Ada Lopez
Chen Wu

Reshaping Objects

Build a new object, or edit the one you have.

  • {name, dept} keeps only those fields, using the field names as keys.
  • {n: .name, d: .dept} renames fields.
  • .name = "New" sets a value.
  • .age |= . + 1 updates a value with a filter.
  • . + {active: true} merges an object, with the right side winning on conflicts.
  • del(.email) removes a key.
  • with_entries(select(.value != null)) drops null-valued keys.
  • keys returns sorted key names, and keys_unsorted preserves document order.
  • to_entries converts an object to an array of {key, value} pairs, and from_entries reverses it.
jq -c '.employees[0] | {n: .name, d: .dept}' employees.json
{"n":"Ada Lopez","d":"Engineering"}

Arrays and Aggregation

Collect, count, and summarize.

  • [.employees[].name] wraps a stream back into an array.
  • length returns array length, object key count, or string character count.
  • map(.salary) applies a filter to every element.
  • add sums numbers, concatenates strings, or merges objects.
  • min, max, min_by(.age), and max_by(.age) find extremes.
  • sort orders an array, and sort_by(.age) orders by a computed key.
  • reverse flips order. Combine with sort_by for descending order.
  • unique removes duplicates and sorts, and unique_by(.dept) deduplicates on a key.
  • group_by(.dept) returns an array of arrays, grouped by a sorted key.
  • flatten collapses nested arrays, and flatten(1) limits the depth.
  • any and all test a whole array, returning a single boolean.
  • range(0; 5) generates numbers, including the start and excluding the end.

add on an empty array returns null, so guard totals with // 0 when the input may be empty.

jq '[.employees[].salary] | add' employees.json
434000

Strings and Numbers

Convert, format, and interpolate.

  • tostring and tonumber convert between types. tonumber fails on text that is not numeric.
  • ascii_downcase and ascii_upcase change case for ASCII only.
  • ltrimstr("pre") and rtrimstr(".suf") remove a prefix or suffix when present.
  • split(",") divides a string into an array, and join(", ") reverses it.
  • test("regex") returns a boolean, match("regex") returns match details, and capture("(?<name>re)") returns named groups.
  • sub("a"; "b") replaces the first match, and gsub("a"; "b") replaces every match.
  • "Hi \(.name)" interpolates a filter into a string.
  • floor, ceil, round, fabs, and sqrt cover common arithmetic.
  • now returns the current Unix timestamp, and todate formats one as ISO 8601.
jq -r '.employees[] | "\(.name) <\(.email)>"' employees.json | head -2
Ada Lopez <ada@acme.example>
Ben Okafor <ben@acme.example>

Defaults and Error Handling

Keep a filter running when the data is imperfect.

  • .missing // "fallback" substitutes when the left side is null or false.
  • .a? returns nothing instead of erroring when the input type is wrong.
  • try .a catch "bad" catches an error and returns a replacement.
  • error("message") raises an error deliberately.
  • empty produces no output, which removes a value from a stream.
  • halt_error exits with a non-zero status, which is useful in scripts.

// treats false as absent, so it is the wrong operator for a boolean field that may legitimately be false.

jq '.employees[0].address.city // "unknown"' employees.json
"unknown"

Output Formats

Control what reaches stdout.

  • @csv formats an array as one comma-separated row, quoting strings.
  • @tsv formats an array as a tab-separated row.
  • @json serializes a value as a JSON string.
  • @base64 encodes, and @base64d decodes.
  • @uri percent-encodes for use in a URL.
  • @sh quotes a value for safe use in a shell command.

@csv and @tsv require an array of scalars, so build one with [...] first, and pair them with -r to strip the outer quotes.

jq -r '.employees[] | [.name, .dept, .salary] | @csv' employees.json | head -2
"Ada Lopez","Engineering",145000
"Ben Okafor","Engineering",118000

Command-Line Flags

Flags change how jq reads input and writes output.

  • -r prints strings raw, without surrounding quotes.
  • -j prints raw output with no trailing newline.
  • -c prints each result on a single line.
  • -n starts with null input instead of reading stdin, which suits --arg-only invocations.
  • -s reads the entire input stream into one array.
  • -e sets the exit status from the output, returning 1 when the result is null or false.
  • -S sorts object keys in the output.
  • --tab indents with tabs, and --indent N sets a space count from 0 to 7.
  • --arg name value passes a string variable, available as $name.
  • --argjson name value passes parsed JSON rather than a string.
  • --slurpfile name file reads a file into an array variable, and --rawfile reads it as one string.
  • --raw-input treats each input line as a string instead of JSON.
  • -f file.jq reads the filter program from a file.

Always pass shell values through --arg rather than string-concatenating them into the program, which keeps quoting correct.

jq -n --arg dept Design --argjson min 90000 \
  '{dept: $dept, floor: $min}'
{
  "dept": "Design",
  "floor": 90000
}

Error Messages and What They Mean

The text jq prints on stderr, and the usual cause.

  • jq: error: syntax error, unexpected ... means the filter failed to compile. Check for an unclosed bracket or quote.
  • Cannot index array with string ("name") means a .field was applied to an array. Add [] to iterate first.
  • Cannot index string with string ("name") means the value is a string, often because -r output was piped back into jq.
  • Cannot iterate over null means [] was applied to a missing key. Use .a[]? to skip it.
  • null (null) has no keys means keys ran against a missing object.
  • Cannot index number with number (0) means an index was applied to a scalar.
  • parse error: Invalid numeric literal means the input is not valid JSON. Check for a shell prompt or log line mixed into the stream.
  • jq: error (at <stdin>:1) prefixes runtime errors, where the number is the input line.

jq exits 0 on success, 1 when -e is set and the output is null or false, 2 on a usage problem, 3 on a compile error, and 5 after halt_error.

  • The jq Cookbook covers the same filters with explanations and full worked examples.
  • The jq Manual is the authoritative specification for every builtin.

References

  • jq Manual, the official reference for jq 1.8, covering every builtin, operator, and flag.
  • jq on GitHub, for release notes and the changelog that records behavior changes between versions.