jq Cheat Sheet

Command-line JSON processing. Filters, selectors, transforms, recipes you actually use.

Basics
.
Identity. Returns the input unchanged. Useful for pretty-printing.
.field
Get value at key field
.foo.bar
Nested access
.["foo bar"]
Bracket access for keys with special chars or spaces
.field?
Optional access (no error if not present)
.[]
Iterate: emit each array element (or object value) as separate output
.[0]
First element of array
.[-1]
Last element of array
.[2:5]
Array slice (zero-indexed, end-exclusive)
f1 | f2
Pipe: feed output of f1 into f2
f1, f2
Concatenate outputs of f1 and f2
CLI Flags
-r
Raw output (strip JSON quotes from strings)
-c
Compact output (no pretty-print)
-s
Slurp all inputs into one array (for multi-doc input)
-R
Raw input (treat each line as a string, not JSON)
-n
No input (use null as input, useful for generating data)
--arg name val
Bind shell variable as $name (string)
--argjson name val
Bind shell variable as $name (parsed JSON)
--slurpfile name file
Read file as JSON array, bind to $name
Selecting & Filtering
select(.x > 5)
Pass through if predicate is true, drop otherwise
select(.role == "admin")
Filter by string equality
select(has("field"))
Keep only objects that have a key
select(.tags | contains(["urgent"]))
Array contains all elements of the given array
select(.name | startswith("foo"))
String prefix check
select(.name | endswith(".json"))
String suffix check
select(.name | test("^a.*"))
Regex match (returns boolean)
.[] | select(.active)
Iterate, keep only those where .active is truthy
Transforming
map(.field)
Apply filter to each element of an array (returns array)
map(. * 2)
Double each value
map(select(.x > 5))
Filter array by predicate (still returns array)
map_values(. + 1)
Apply filter to each value of an object
to_entries
Object to array of {key, value} pairs
from_entries
Reverse: array of pairs back to object
with_entries(.value += 1)
Convenience: to_entries | map(...) | from_entries
. + {newkey: "val"}
Merge object with another (right wins on conflict)
.foo |= ascii_downcase
Update assign: replace .foo with the result of running it through filter
del(.field)
Delete a key from an object
del(.[0])
Delete first element of array
Aggregation
length
Length of array, string, or object (key count)
keys
Sorted array of object keys (or array indices)
values
Array of object values
add
Sum of array elements (concat for strings)
min, max
Min or max of array
min_by(.x), max_by(.x)
Element with min or max field value
unique
Sort and remove duplicates
unique_by(.x)
Unique by a field
group_by(.x)
Group elements by field, returns array of arrays
sort
Sort array
sort_by(.x)
Sort by field
reverse
Reverse an array
Object & Array Construction
{a: .x, b: .y}
Build object from input fields
{name, email}
Shorthand: {name: .name, email: .email}
[.[] | .x]
Wrap iteration back into an array
[.x, .y, .z]
Build array from fields
{(.k): .v}
Use a value as a key
[range(0;10)]
Generate array [0, 1, ..., 9]
Conditionals & Default Values
if .x then .y else .z end
Conditional expression
if .x then .y elif .a then .b else .c end
elif chain
.x // "default"
Alternative: if .x is null or false, use "default"
try .field catch null
Catch errors, replace with null
.field?
Shorthand for try .field catch empty
Strings
"prefix-\(.field)"
String interpolation
split("/")
Split string into array
join(",")
Join array of strings
ascii_downcase
Lowercase ASCII letters
ascii_upcase
Uppercase ASCII letters
tostring
Convert any value to string
tonumber
Parse string as number
gsub("foo"; "bar")
Global string replace (regex)
@csv, @tsv
Format array as CSV or TSV row
@base64, @base64d
Base64 encode and decode
@uri
URL-encode a string
Recursive & Path
..
Recursive descent: yield every value at any depth
.. | strings
Every string anywhere in the document
.. | numbers
Every number anywhere
paths
All paths in the structure
leaf_paths
Paths to all leaf values
getpath(["a","b"])
Get value at a path
setpath(["a","b"]; "val")
Set value at a path
Common Recipes
Extract a single field from each item in an array
cat users.json | jq '.[].email'
Filter and project
jq '.users | map(select(.active) | {id, email})' file.json
Count items by group
jq 'group_by(.country) | map({country: .[0].country, count: length})'
Get top 5 by score, descending
jq 'sort_by(.score) | reverse | .[0:5]'
Convert array of objects to CSV
jq -r '.[] | [.id, .name, .email] | @csv' file.json
Pretty-print compact JSON from a file or pipe
cat compact.json | jq '.'
Curl an API and extract one field
curl -s https://terminalfeed.io/api/btc-price | jq '.data.price'
Sum a field across an array
jq '[.items[].amount] | add'
Pass a shell variable as a string
jq --arg name "Alice" '.users[] | select(.name == $name)'
Pass a shell variable as parsed JSON
jq --argjson min 5 '.items | map(select(.score >= $min))'
Combine multiple JSON files into a single array
jq -s '.' file1.json file2.json file3.json
Find every value containing "error" anywhere in the structure
jq '.. | strings | select(contains("error"))'