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..companyreturns one field. Returnsnullwhen the key is absent.."odd key"returns a field whose name contains spaces or punctuation..a.b.cwalks nested objects. Any missing level yieldsnull..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.jsonAda LopezFiltering 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 withand,or, andnot.select(.name | test("^[ab]"; "i"))matches a regular expression. The second argument holds flags, whereimeans 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.jsonAda Lopez
Chen WuReshaping 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 |= . + 1updates 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.keysreturns sorted key names, andkeys_unsortedpreserves document order.to_entriesconverts an object to an array of{key, value}pairs, andfrom_entriesreverses 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.lengthreturns array length, object key count, or string character count.map(.salary)applies a filter to every element.addsums numbers, concatenates strings, or merges objects.min,max,min_by(.age), andmax_by(.age)find extremes.sortorders an array, andsort_by(.age)orders by a computed key.reverseflips order. Combine withsort_byfor descending order.uniqueremoves duplicates and sorts, andunique_by(.dept)deduplicates on a key.group_by(.dept)returns an array of arrays, grouped by a sorted key.flattencollapses nested arrays, andflatten(1)limits the depth.anyandalltest 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.json434000Strings and Numbers
Convert, format, and interpolate.
tostringandtonumberconvert between types.tonumberfails on text that is not numeric.ascii_downcaseandascii_upcasechange case for ASCII only.ltrimstr("pre")andrtrimstr(".suf")remove a prefix or suffix when present.split(",")divides a string into an array, andjoin(", ")reverses it.test("regex")returns a boolean,match("regex")returns match details, andcapture("(?<name>re)")returns named groups.sub("a"; "b")replaces the first match, andgsub("a"; "b")replaces every match."Hi \(.name)"interpolates a filter into a string.floor,ceil,round,fabs, andsqrtcover common arithmetic.nowreturns the current Unix timestamp, andtodateformats one as ISO 8601.
jq -r '.employees[] | "\(.name) <\(.email)>"' employees.json | head -2Ada 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 isnullorfalse..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.emptyproduces no output, which removes a value from a stream.halt_errorexits 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.
@csvformats an array as one comma-separated row, quoting strings.@tsvformats an array as a tab-separated row.@jsonserializes a value as a JSON string.@base64encodes, and@base64ddecodes.@uripercent-encodes for use in a URL.@shquotes 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",118000Command-Line Flags
Flags change how jq reads input and writes output.
-rprints strings raw, without surrounding quotes.-jprints raw output with no trailing newline.-cprints each result on a single line.-nstarts withnullinput instead of reading stdin, which suits--arg-only invocations.-sreads the entire input stream into one array.-esets the exit status from the output, returning 1 when the result isnullorfalse.-Ssorts object keys in the output.--tabindents with tabs, and--indent Nsets a space count from 0 to 7.--arg name valuepasses a string variable, available as$name.--argjson name valuepasses parsed JSON rather than a string.--slurpfile name filereads a file into an array variable, and--rawfilereads it as one string.--raw-inputtreats each input line as a string instead of JSON.-f file.jqreads 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.fieldwas applied to an array. Add[]to iterate first.Cannot index string with string ("name")means the value is a string, often because-routput was piped back into jq.Cannot iterate over nullmeans[]was applied to a missing key. Use.a[]?to skip it.null (null) has no keysmeanskeysran against a missing object.Cannot index number with number (0)means an index was applied to a scalar.parse error: Invalid numeric literalmeans 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.
Related Reading
- 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.

Comments #