JQ
jq is a stream-oriented transformation language. Filters consume an input and may produce zero, one, or many outputs
CLI Options
Input
-n
Use null as input — build data from scratch.
jq -n 'range(3)'
-R
Read input as raw strings (not JSON). Each line becomes a string.
printf 'foo\nbar\n' | jq -R '.' # "foo" "bar"
-s
Slurp — read the entire input stream into a single array.
printf '{"x":1}\n{"x":2}\n' | jq -s 'map(.x) | add' # 3
Output
-r
Raw output — print strings without JSON quotes/escaping.
$ jq -n '"hello"'
"hello"
$ jq -rn '"hello"'
hello
-b
Ensure no CRLF conversion on Windows.
$ jq -nb '42'
-c
Compact output — each output on a single line.
$ jq -n '[1,2]'
[
1,
2
]
$ jq -nc '[1,2]'
[1,2]
Variables
--arg
Set a variable $name to a string value.
jq -n --arg name foo '{$name}' # {"name":"foo"}
--argjson
Set a variable $name to a JSON value.
jq -n --argjson n 42 '{$n}' # {"n":42}
--args
Pass positional arguments as $ARGS.positional (strings).
jq -n '$ARGS.positional' --args hello world # ["hello","world"]
--jsonargs
Pass positional arguments as JSON values.
jq -n '$ARGS.positional' --jsonargs 1 2 3 # [1,2,3]
Core language
Path Expr
. Identity (root)
.foo Object field access
.foo.bar Nested object field access
."wired-key" Key with special chars (quoted)
.foo? Safe access (null if missing)
.[] Iterate array elements
.[]? Safe iterate overy arrays/objects
.[0] Index by number (also .[0] = .[0] |= ...)
.[-1] Last element (negative index)
.[1:5] Array slice from index 1 (inclusive) to index 5 (exclusive)
.[1:]
.[:5]
Construction
Array & Object Construction
[1, 2, .a] Build array
{key: .name} Build object
{($k): .v} Computed key
{name} Shorthand for {name: .name}
Operator
|
Pipe the output of a filter as input to the next filter.
. | .name Feed current value into field access
. | map(. + 1) Feed array into map
keys | .[] Chain filters — keys then iterate
The fundamental composition primitive: everything left of | is evaluated, and its output becomes . on the right.
jq -n '1 | . + 2' # 3
jq -n '[1,2,3] | length' # 3
jq -n '{a:1,b:2} | keys | .[]' # "a" "b"
//
Alternative operator — returns left operand if it is not null or false, otherwise returns right operand. Useful for defaults.
.a // "default" Use .a if present, else "default"
null // 42 → 42
false // 42 → 42 (false is falsy too)
"" // "fallback" → "" (empty string is truthy)
?
? suppresses errors from a filter. Commonly paired with // for fallback defaults.
.foo? return null if key missing
.[]? return empty if value is not iterable
.foo?.bar? // "n/a" chain safe accesses with default
jq -n '{} | .foo? // "no"' # "no"
jq -n '5 | .[]? // "empty"' # "empty"
jq -n 'null | .a?.b? // 0' # 0
,
Produce multiple values from a single input as a stream.
Each expression after , generates a separate output.
.name, .age Output name and age as separate values
1, 2, 3 Stream of three numbers
[.x, .x * 2] Build array from multiple expressions
jq -n '1, 2, 3' # 1 2 3 (three lines)
jq -n '{a:1,b:2} | .a, .b' # 1 2
jq -nc '[1,2,3] | .[], .[]' # 1 1 2 2 3 3
as
Bind the current value (or destructured parts) to a variable for later use.
. as $x | $x + 1
.a as $val | {$val}
{a, b} as {$x, $y} | $x + $y
.[] as $item | {item: $item}
Variables are prefixed with $ and stay in scope for the rest of the pipeline.
jq -n '1 as $x | $x + 2' # 3
jq -n '[1,2,3] | . as $a | $a | add' # 6
jq -n '{a:1,b:2} | {a} as {$a} | $a' # 1
\(exp)
String interpolation
jq -rn '42 | "The input was \(.), which is one less than \(.+1)"'
Assignment
= Assign
|= Update value (e.g. .arr |= sort)
+= -= *= /= %= Arithmetic update-assignment
jq -n '[1,2,3] | .[0] = 99' # [99,2,3]
jq -n '{a:1} | .a |= . + 1' # {"a":2}
jq -n '{a:1} | .a = (.a | . + 1)' # {"a":2}
jq -n '{a:1} | .a += 1' # {"a":2}
jq -n '{a:10} | .a /= 2' # {"a":5}
Arithmetic
.a + .b Add (numbers) or concat (strings/arrays)
.a - .b Subtract (or set diff: [1,2] - [2,3] → [1])
.a * .b Multiply (or repeat string: "a" * 3 → "aaa")
.a / .b Divide (or split string: "a,b" / "," → ["a","b"])
.a % .b Modulo
jq -n '3 + 4 * 2' # 11 (* before +)
jq -n '[1,2] + [3,4]' # [1,2,3,4]
jq -n '{"a":1} + {"b":2}' # {"a":1,"b":2}
jq -n '{"a":1} * {"a":2,"b":3}' # {"a":2,"b":3} (merge, rhs wins)
jq -n '"a" * 3' # "aaa"
jq -n '"a,b" / ","' # ["a","b"]
Comparison
.a == .b Equal (type-sensitive, no coercion)
.a != .b Not equal
.a > .b Greater than
.a >= .b Greater or equal
.a < .b Less than
.a <= .b Less or equal
Logic
.a > 1 and .b < 5 Both true
.a > 1 or .b < 5 Either true
.flag | not Negate via pipe (preferred idiom)
.a > 1 and (.b | not) Group with parens
Standard library
Basic
length
Length of string, array, or object.
jq -n '"abc" | length'
keys / keys_unsorted
Return the keys of an object (sorted/insertion-order).
jq -n '{b:1,a:2} | keys' # ["a","b"]
jq -n '{b:1,a:2} | keys_unsorted' # ["b","a"]
to_entries / from_entries / with_entries
Convert between objects and arrays of key-value entries.
jq -n '{a:1} | to_entries'
jq -n '[{"key":"a","value":1}] | from_entries'
jq -n '{a:1,b:2} | with_entries(.value *= 2)'
Selection
numbers / strings / booleans / arrays / objects / nulls
Type filter functions — return only values of matching type.
jq -n '[1, "a", true, null] | map(numbers)' # [1]
jq -n '[1, "a", true, null] | map(strings)' # ["a"]
type
Return the type of a value as a string.
$ jq -nc '[0, false, [], {}, null, "hello"] | map(type)'
["number","boolean","array","object","null","string"]
select
Filter items by condition.
jq -n '[1,2,3] | map(select(. > 1))'
Conversions
tonumber / toboolean / tostring
Convert between string and number.
jq -n '"42" | tonumber'
jq -n '"true" | toboolean'
jq -n '42 | tostring'
fromjson / tojson
Parse a JSON string or serialize to JSON string.
jq -n '"{\"a\":1}" | fromjson' # {"a":1}
jq -n '{a:1} | tojson' # "{\"a\":1}"
Stream generators
empty
Return nothing (zero outputs). Useful as a no-op or to suppress output in conditional branches.
jq -n 'empty' # (no output)
jq -n '[1, empty, 2]' # [1, 2]
jq -n 'if true then 42 else empty end' # 42
range
Generate a sequence of numbers.
jq -n 'range(3)' # 0 1 2
jq -n 'range(1; 5)' # 1 2 3 4
jq -n 'range(0; 10; 3)' # 0 3 6 9
recurse
Recursively descend into nested structures.
.. is alias for recurse.
jq -n '{a:{b:1}} | recurse'
jq -n '10 | recurse(. - 1; . > 0)'
Stream consumers
add
Sum array elements.
jq -n '[1,2,3] | add' # 6
jq -n '[] | add' # null
jq -n '[{a:1},{a:2}] | add(.[].a)' # 3
first / last
Return first or last element.
jq -n '[1,2,3] | first' # 1
jq -n '[1,2,3] | last' # 3
limit
Limit the number of outputs from a stream.
jq -n '[1,2,3,4,5] | limit(3; .[])' # 1, 2, 3
reduce
Accumulate array elements into a single value. Takes (init; update) where
. is the accumulator and $item is each element.
jq -n '[1,2,3] | reduce .[] as $item (0; . + $item)' # 6
foreach
Iterate with state and emit a value per element. Takes (init; update; extract).
$ jq -nc '[1,2,3] | foreach .[] as $item (0; . + $item; {idx: ., sum: .})'
{"idx":1,"sum":1}
{"idx":3,"sum":3}
{"idx":6,"sum":6}
any / all
Check if any/all elements satisfy a condition.
jq -n '[1,2,3] | any(. > 2)' # true
jq -n '[1,2,3] | all(. > 0)' # true
jq -n '[1,2,3] | any' # true (any truthy)
jq -n '[] | any' # false
Updates
map / map_values
Apply a filter to each array element / object value.
jq -n '[1,2,3] | map(. * 2)'
jq -n '{a:1,b:2} | map_values(. + 1)'
walk
Recursively process all elements in a tree structure.
$ jq -nc '{a:{b:"c"},d:"e"} | walk(if type == "string" then ascii_upcase else . end)'
{"a":{"b":"C"},"d":"E"}
del
Delete a key from an object.
jq -n '{a:1,b:2} | del(.b)'
Paths
pick
Select only specified keys from an object.
jq -n '{a:1,b:2,c:3} | pick(.a, .c)' # {"a":1,"c":3}
paths / setpath / getpath / delpaths
Inspect and manipulate nested paths.
jq -n '{a:{b:1},c:2} | paths'
jq -n '{a:{b:1},c:2} | paths(scalars)'
jq -n '{} | setpath(["a","b"]; 1)' # {"a":{"b":1}}
jq -n '{"a":{"b":1}} | getpath(["a","b"])' # 1
jq -n '{"a":{"b":1,"c":2}} | delpaths([["a","b"]])' # {"a":{"c":2}}
Membership
contains / inside
Check if a value contains another (strings, arrays, objects).
jq -n '"foobar" | contains("foo")' # true
jq -n '[1,3,2] | contains([1,2])' # true
jq -n '{"a":1,"b":2} | contains({a:1})' # true
inside is the inverse — checks if input is inside argument.
jq -n '"foo" | inside("foobar")' # true
indices
Find all indices where a value/pattern occurs.
jq -n '"abcabc" | indices("b")' # [1,4]
jq -n '[1,2,1,2] | indices(1)' # [0,2]
index
Find the first index of a value in an array or string.
jq -n '"abcabc" | index("b")' # 1
jq -n '[1,2,1,2] | index(1)' # 0
Arrays
sort / sort_by
Sort array; sort_by(f) sorts by the result of applying f to each element.
jq -n '[3,1,2] | sort'
jq -n '[{"age":2},{"age":1}] | sort_by(.age)'
group_by
Group elements into array of arrays based on a key expression.
$ jq -nc '[{"name":"a","type":"x"},{"name":"b","type":"y"},{"name":"c","type":"x"}] | group_by(.type)'
[[{"name":"a","type":"x"},{"name":"c","type":"x"}],[{"name":"b","type":"y"}]]
group_by(.x) requires prior sort_by(.x)
unique / unique_by
Remove duplicate elements. unique uses value equality; unique_by(f) uses the result of f as the key.
jq -n '[1,2,1,3] | unique' # [1,2,3]
jq -n '[{"x":1},{"x":2},{"x":1}] | unique_by(.x)' # [{"x":1},{"x":2}]
min / max / min_by / max_by
Find minimum or maximum values.
jq -n '[3,1,2] | min' # 1
jq -n '[3,1,2] | max' # 3
jq -n '[{"x":2},{"x":1}] | min_by(.x)' # {"x":1}
reverse
Reverse an array.
jq -n '[1,2,3] | reverse' # [3,2,1]
transpose
Transpose a matrix (array of arrays).
jq -n '[[1,2],[3,4]] | transpose' # [[1,3],[2,4]]
flatten
Flatten nested arrays to a specified depth (default: infinite).
jq -n '[[1,[2]],[3]] | flatten' # [1,2,3]
jq -n '[[1,[2]],[3]] | flatten(1)' # [1,[2],3]
Text strings
ascii_downcase / ascii_upcase
Convert string to lowercase/uppercase.
jq -n '"Hello" | ascii_downcase' # "hello"
jq -n '"Hello" | ascii_upcase' # "HELLO"
join
Join array elements with a separator string.
jq -n '[1,2,3] | join(", ")'
Text string formatting
@json: Format value as JSON string, e.g.jq -nc '42 | @json'→"42"@csv: Convert array to CSV line, e.g.jq -nr '["a","b"] | @csv'→"a","b"@tsv: Convert array to TSV line, e.g.jq -nr '["a","b"] | @tsv'→a\tb@html: Escape HTML special chars, e.g.jq -nr '"<script>" | @html'→<script>@uri: Percent-encode URI component, e.g.jq -nr '"hello world" | @uri'→hello%20world@base64: Base64 encode string, e.g.jq -nr '"hello" | @base64'→aGVsbG8=@base64d: Base64 decode string, e.g.jq -nr '"aGVsbG8=" | @base64d'→hello@sh: Escape for shell use (single-quote wrap), e.g.jq -nr '"it'\''s" | @sh'→'it'\''s'@text: Convert to string, e.g.jq -nc '42 | @text'→"42"
Regular expressions
test
Check if string matches regex — returns true/false.
jq -n '"hello 42" | test("\\d+")'
jq -n '"Hello" | test("^[a-z]+$"; "i")'
match
Return match objects with details (offset, length, captures).
$ jq -nc '"abc123" | match("[a-z]+|\\d+"; "g")'
{"offset":0,"length":3,"string":"abc","captures":[]}
{"offset":3,"length":3,"string":"123","captures":[]}
capture
Extract named groups into an object.
$ jq -nc '"2024-01-15" | capture("(?<y>\\d+)-(?<m>\\d+)-(?<d>\\d+)")'
{"y":"2024","m":"01","d":"15"}
split / splits
Split string by regex. split returns array; splits streams results.
$ jq -rn '"a,b" | split(",")'
[
"a",
"b"
]
$ jq -rn '"a,b" | splits(",")'
a
b
sub / gsub
Replace matched substrings. sub replaces first match, gsub replaces all.
jq -rn '"hello world" | sub("\\w+"; "***")' # *** world
jq -rn '"hello world" | gsub("\\w+"; "***")' # *** ***
Capture groups in replacement via $1, $2, etc.:
jq -rn '"2024-01-15" | sub("(?<y>\\d+)-(?<m>\\d+)-(?<d>\\d+)"; "\(.y).\(.m).\(.d)")'
Date & Time
now
Return the current time as Unix epoch seconds (float).
jq -n 'now' # 1705314600.22693
fromdate
Parse an ISO 8601 datetime string to Unix epoch seconds.
jq -n '"2024-01-15T10:30:00Z" | fromdate' # 1705314600
todate
Convert Unix epoch seconds to an ISO 8601 datetime string.
jq -n 'now | todate' # "2024-05-18T12:34:56Z"
strftime
Formats a datetime (epoch seconds) to a string using a format specifier.
jq -n 'now | strftime("%Y-%m-%d")' # "2024-05-18"
strflocaltime
Like strftime but formats in local timezone.
jq -n 'now | strflocaltime("%Y-%m-%d %H:%M:%S")'
strptime
Parses a string to array representation using a format specifier.
jq -n '"2024-01-15" | strptime("%Y-%m-%d")' # [2024,0,15,0,0,0,1,14]
mktime / gmtime
Convert between array representation and epoch seconds.
jq -n '[2024,0,15,0,0,0,1,14] | mktime' # 1705305600
jq -n '1705305600 | gmtime' # [2024,0,15,0,0,0,1,14]
I/O
inputs
Read remaining input values (useful with -n for streaming).
printf '1\n2\n3\n' | jq -n '[inputs] | add' # 6
debug
Print value to stderr, pass through unchanged. Useful for tracing in pipelines.
jq -n '1, 2 | debug'
stderr output: ["DEBUG:",1] ["DEBUG:",2]
try / catch / error
Handle errors without halting the pipeline. try expr silently suppresses
errors; try expr catch handler runs handler with the error message as ..
jq -n '3 | try .a' # (nothing)
jq -n '3 | try .a catch "na"' # "na"
jq -n 'try error("fail") catch "caught: \(.)"' # "caught: fail"
$ENV
$ENV is an object representing the environment variables as set when the jq program started. $ENV is readonly
$ENV Object of all environment variables
$ENV | keys List all env var names
$ENV.PATH Access env var via variable
$ARGS.named
Access named arguments passed via --arg / --argjson programmatically.
jq -n --arg a 1 --argjson b 2 '$ARGS.named' # {"a":"1","b":2}
$ARGS.positional
Access positional arguments passed via --args / --jsonargs programmatically.
jq -n '$ARGS.positional' --args hello world # ["hello","world"]
jq -n '$ARGS.positional' --jsonargs 1 2 3 # [1,2,3]
Defining Functions
def add1: . + 1;
def map(f): [.[] | f]; # f is a filter parameter (def filter)
def add(x; y): x + y; # Multi-arg (note semicolons)