jq Cheatsheet

1.7

Wrangle JSON like a pro

Essential jq filters and expressions for JSON wrangling

Official docs →
Filters & pipesArray operationsOne-liners

Last updated: 2026-03-29

jq is sed for JSON — a lightweight, flexible command-line processor that turns messy API responses and config files into exactly the data you need. If you've ever squinted at a wall of minified JSON trying to find one nested field, jq is the tool that makes you wonder how you survived without it.

The mental model is simple: jq is a pipeline. Data flows in from the left, gets transformed by filters, and comes out the right side. The . is your starting point — it means "the whole input." From there you drill down with .field, iterate with .[], and chain filters with |. It's functional programming disguised as a command-line tool, and once the pipe-thinking clicks, you'll reach for jq the way you reach for grep.

We've organized this by the kind of problem you're solving rather than by jq's internal taxonomy. Start with Basic Filters to pull values out of JSON, then move to Array and Object Operations when you need to reshape data. The One-Liners section at the end is where the real magic lives — battle-tested patterns you can copy-paste into your terminal right now.

One thing to internalize early: jq expressions are composable. Every filter takes input and produces output, so you can chain them endlessly with |. That select(...) you wrote? Pipe it into map(...). Pipe that into sort_by(...). It's filters all the way down.

Basic Filters
.
Identity — output the entire input unchanged
.field
Extract a top-level field by name
.field.nested
Drill into nested objects with dot notation
.["hyphenated-key"]
Access fields with special characters in the name
.[]
Iterate over all elements in an array or values in an object
.[0]
Get the first element of an array
.[-1]
Get the last element of an array
.[2:5]
Slice an array — elements at index 2, 3, and 4
.field?
Try to access a field — suppress errors if it does not exist
.[] | .name
Iterate an array and extract a field from each element
Types & Values
null
The JSON null value
length
String length, array count, or number of object keys
keys
Get all keys of an object as a sorted array
keys_unsorted
Get all keys of an object in original order
values
Get all values of an object as an array
type
Return the type as a string: "object", "array", "string", "number", "boolean", or "null"
has("field")
Check if an object has a specific key (returns true/false)
in({"a":1})
Check if a key exists in a given object
empty
Produce no output — useful for conditional suppression
env.VAR
Access environment variable VAR
String Operations
split(",")
Split a string by delimiter into an array
join(",")
Join an array of strings with a delimiter
test("regex")
Test if a string matches a regex (returns true/false)
match("regex")
Return match object with offset, length, and captures
capture("(?<name>\\w+)")
Named capture groups returned as an object
gsub("old"; "new")
Replace all occurrences of a regex pattern
sub("old"; "new")
Replace first occurrence of a regex pattern
ascii_downcase
Convert string to lowercase
ascii_upcase
Convert string to uppercase
ltrimstr("prefix")
Remove a prefix from a string if present
rtrimstr("suffix")
Remove a suffix from a string if present
@base64
Encode a string as base64
@base64d
Decode a base64 string
@uri
Percent-encode a string for URLs
@html
Escape HTML special characters
tostring
Convert any value to its string representation
tonumber
Parse a string as a number
Array Operations
map(f)
Apply filter f to every element and collect results
map_values(f)
Apply filter f to every value (works on objects too)
select(condition)
Keep only elements where condition is true
sort
Sort an array of comparable values
sort_by(.field)
Sort array of objects by a specific field
reverse
Reverse the order of an array
group_by(.field)
Group array elements by a field into sub-arrays
unique
Remove duplicate values from a sorted array
unique_by(.field)
Remove duplicates by a specific field
flatten
Flatten nested arrays into a single level
flatten(1)
Flatten one level of nesting
first
Get the first output from a generator
last
Get the last output from a generator
limit(n; expr)
Take only the first n outputs from an expression
add
Sum numbers, concatenate strings, or merge arrays/objects
any(condition)
True if any element satisfies the condition
all(condition)
True if all elements satisfy the condition
min_by(.field)
Get the element with the smallest field value
max_by(.field)
Get the element with the largest field value
indices(value)
Get all indices where value appears in the array
contains([values])
Check if array contains all specified values
inside([values])
Check if input is contained within the given value
Object Operations
to_entries
Convert {"a":1} to [{"key":"a","value":1}]
from_entries
Convert [{"key":"a","value":1}] back to {"a":1}
with_entries(f)
Shorthand for to_entries | map(f) | from_entries
+ (objects)
Merge two objects — right side wins on key conflicts
* (objects)
Recursively merge two objects
{name, age}
Select specific fields from an object
{newname: .oldname}
Rename a field while extracting
del(.field)
Remove a field from an object
paths
List all paths to leaf values as arrays
getpath(["a","b"])
Get value at a specific path — like .a.b
setpath(["a","b"]; val)
Set value at a specific path
delpaths([path])
Delete values at specified paths
Conditionals & Comparisons
if . then A else B end
Conditional expression — else clause is optional
// (alternative)
Use the right value if left is null or false
a == b
Equality comparison (deep equality for objects/arrays)
a != b
Inequality comparison
and, or, not
Boolean operators
try f
Run filter f, suppress errors silently
try f catch msg
Run filter f, use msg expression on error
f as $var | expr
Bind a value to a variable for use in the pipeline
reduce .[] as $x (init; update)
Fold an array into a single value
label $out | foreach ...
Streaming loop with break support
Output Formatting
-r (--raw-output)
Output raw strings without JSON quotes
-c (--compact-output)
Minify — print JSON on a single line
-S (--sort-keys)
Sort object keys alphabetically in output
-e (--exit-status)
Set exit code based on output: 0 for true/non-null, 1 for false/null
-n (--null-input)
Do not read input — useful with --argjson or --slurpfile
-s (--slurp)
Read all inputs into a single array
--arg name val
Pass a string value as a $name variable
--argjson name val
Pass a JSON value as a $name variable
--slurpfile name file
Load a JSON file as a $name variable (array)
@csv
Format an array of arrays as CSV
@tsv
Format an array of arrays as TSV
@json
Serialize a value as a JSON string (for embedding)
@text
Convert to text output

One-Liners

Real-world patterns you will actually use. Copy, paste, adapt.

One-Liners
jq . file.json
Pretty-print a JSON file
jq -r ".[] | .name" file.json
Extract a field from every object in an array
jq "[.[] | select(.active == true)]"
Filter an array to only matching elements
jq -r ".[] | [.name, .email] | @csv"
Convert JSON array to CSV
jq -s "." file1.json file2.json
Merge multiple JSON files into one array
jq -r "keys[]" file.json
List all top-level keys
jq ".[] | select(.price > 100) | .name"
Find names where price exceeds a threshold
jq "group_by(.status) | map({(.[0].status): length}) | add"
Count items per group
jq --arg q "$QUERY" '.[] | select(.name | test($q; "i"))'
Case-insensitive search using a shell variable
jq -r "to_entries[] | \"\(.key)=\(.value)\""
Convert JSON object to key=value lines
jq "[.[] | {id, name}]"
Reshape objects — keep only specific fields
jq -r ".results | sort_by(.date) | reverse | .[0]"
Get the most recent entry from a sorted array
curl -s api.example.com | jq .
Pretty-print API response inline
jq -s "map(.items) | flatten | unique_by(.id)"
Merge and deduplicate paginated API responses
jq 'walk(if type == "string" then gsub("\\n"; " ") else . end)'
Recursively clean up newlines in all string values

Use -r (raw output) whenever you pipe jq into another command. Without it, strings come wrapped in quotes, and those quotes will haunt your shell scripts. jq -r '.name' gives you Alice, not "Alice".

The // operator is jq's null coalescing — it returns the right side when the left is null or false. Perfect for defaults: .config.timeout // 30. It's one of those two-character combos that saves you from writing a full if-then-else ninety percent of the time.

When you need to combine data from multiple files or API responses, reach for --slurp (-s). It reads all inputs into a single array, so you can add objects together, flatten arrays, or zip data across files.

Use --arg and --argjson to pass shell variables into jq safely. Never interpolate shell variables directly into jq expressions — it breaks on special characters and opens you up to injection. jq --arg name "$USER" '.[] | select(.name == $name)' is the right way.

The @base64d filter is a lifesaver when working with Kubernetes secrets or JWTs. Pipe a base64-encoded value through jq -r '.data.password | @base64d' and get the plaintext without leaving your pipeline.

Chain to_entries, map, and from_entries (or use the shorthand with_entries) to transform object keys and values in one pass. Want to prefix every key? with_entries(.key = "prefix_" + .key). It's the object equivalent of map for arrays.

If jq's error messages are cryptic, add debug anywhere in your pipeline to see what's flowing through at that point. It prints to stderr without disrupting your output. Think of it as console.log for jq: .[] | debug | select(.active).

Related Tools