jq JSON processor

Version 1.7 · source

Start here

jq . <file>
Pretty-print JSON
jq '.<key>'
Pick a field
jq '.[]'
Iterate an array
jq '.[] | select(.<key> == <v>)'
Filter items
jq -r '.<key>'
Raw string, no quotes
jq -c .
One line per value
jq '{<a>, <b>: .<c>}'
Build an object
jq -n '<expr>'
Run without input

Concepts

  1. Input JSON file or stdin
  2. Filter .a | .b[] | f
  3. Output pretty by default
Each stage runs once per value it receives

Command-line flags

jq -r '<filter>'
Print strings without quotes
jq -c '<filter>'
Compact, one value per line
jq -n '<filter>'
Use null as input, read nothing
jq -s '<filter>' <file>
Slurp all inputs into one array
jq -R '<filter>' <file>
Read each line as a string
jq -e '<filter>'
Exit 1 if last output is false/null, 4 if none
jq -S . <file>
Sort object keys
jq --arg <name> <value> '$<name>'
Pass a string variable
jq --argjson <name> '<json>' '$<name>'
Pass a JSON variable
jq -f <script.jq> <file>
Load the filter from a file
jq -j '<filter>'
Raw output with no newline after each value
jq --raw-output0 '<filter>'
NUL-separated raw output
Pairs with xargs -0.
jq --rawfile <name> <file> '$<name>'
Read a file into a string variable
jq -n '$ARGS.positional' --jsonargs <json>...
Pass positional JSON values
jq --tab . / jq --indent <n> .
Change indentation
jq --slurpfile <name> <file> '$<name>'
Load a file as an array variable
jq --args '<filter>' <a> <b>
Positional strings in $ARGS.positional
jq -C . <file> | less -R
Keep colours in a pager
jq --stream . <file>
Emit [path,leaf] events for huge files

Selecting

.
The whole input
.<key>
Object field
.<key>.<sub>
Nested field
.[<n>]
Array element, negative counts from end
.[<a>:<b>]
Array or string slice
.[]
Every element or value
.<key>?
Field, suppress errors
.["<key>"]
Field with odd characters
..
Recurse into every value
paths / paths(<cond>)
List the path to every value
.a, .b
Several outputs from one input
getpath(["a",0])
Value at a path array
pick(.a, .b.c)
Keep only the given paths

Filtering and logic

select(<cond>)
Keep inputs where cond is true
map(<f>)
Apply f to each array element
map_values(<f>)
Apply f to each object value
== != < > <= >=
Compare values
and / or / not
Combine conditions
<a> // <default>
Use default if a is null or false
if <cond> then <a> else <b> end
Conditional
else is optional; without it the input passes through.
test("<regex>")
Regex match, returns boolean
has("<key>")
Object contains key
values / strings / numbers / objects / arrays
Keep only values of that type, e.g. .. | strings
contains(<x>) / inside(<x>)
Substring or subset test
any(<f>) / all(<f>)
Does some or every element match
<f> as $<x> | <expr>
Bind each output of f to a variable
The variable is visible to the right of the pipe, e.g. .a[] as $x | $x.
inputs
Read all remaining inputs (use with -n)
jq -n '[inputs]' a.json b.json collects every value.
try <f> catch <g>
Handle errors instead of aborting
empty
Output nothing, drops the value
error("<msg>")
Raise an error

Constructing

{<a>, <b>: .<c>}
Build an object, shorthand for {a: .a}
[<f>]
Collect all outputs into an array
{(.<key>): .<v>}
Computed key
"<text> \(.<key>)"
String interpolation
.a + .b
Add numbers, join strings, arrays, objects
.a * .b
Multiply, or deep-merge objects
$ENV.<NAME> / env.<NAME>
Environment variable
.<key> = <v>
Set a field
.<key> |= <f>
Update a field with a filter
.<key> += <n>
Arithmetic update
del(.<key>)
Remove a field or element
del(.[] | select(<cond>))
Remove matching elements
to_entries / from_entries / with_entries(<f>)
Object to key-value pairs and back
walk(<f>)
Apply f to every value bottom-up

Arrays and aggregation

length
Size of array, object, string
keys
Sorted object keys or array indexes
keys_unsorted
Object keys in original order
sort / sort_by(.<key>)
Sort array
group_by(.<key>)
Group into sub-arrays
unique / unique_by(.<key>)
Remove duplicates
min_by(.<key>) / max_by(.<key>)
Smallest or largest element
add
Sum numbers or concatenate
first / last / nth(<n>)
Pick by position
limit(<n>; <f>)
Take first n outputs
flatten
Flatten nested arrays
reverse
Reverse an array
Strings: explode | reverse | implode.
index(<x>) / indices(<x>)
Find position(s)
range(<n>)
Count from 0 to n-1
reduce <src> as $x (<init>; <update>)
Fold into one value
transpose
Swap rows and columns

Strings and formats

tostring / tonumber
Convert type
type
Name of the value type
split("<sep>") / join("<sep>")
Split and join strings
ascii_downcase / ascii_upcase
Change case
ltrimstr("<s>") / rtrimstr("<s>")
Strip a prefix or suffix
startswith("<s>") / endswith("<s>")
Prefix or suffix test
sub("<re>"; "<new>")
Replace first regex match
gsub("<re>"; "<new>")
Replace all matches
capture("(?<name>...)")
Named groups to object
@csv / @tsv
Array to CSV or TSV row (use with -r)
tojson / fromjson
Encode to or parse a JSON string
@json / @text
Encode as JSON or plain string
@sh
Quote for shell
@uri
Percent-encode
@base64 / @base64d
Encode or decode base64
@html
Escape HTML
todate / fromdate
Epoch seconds and ISO 8601
fromdate needs YYYY-MM-DDTHH:MM:SSZ, no fractions or offsets.
now
Current epoch time
debug / debug("<msg>")
Print to stderr, pass the value on

Recipes

JSON array to CSV (headers from first object)
jq -r '(.[0] | keys_unsorted) as $k  | $k, (.[] | [.[$k[]]]) | @csv' <file>
Count items per group
jq 'group_by(.<key>)  | map({<key>: .[0].<key>, n: length})' <file>
Edit a file in place
jq '.<key> = "<new>"' <file> > tmp.json \  && mv tmp.json <file>
Feed values to a shell loop
jq -r '.[].<key>' <file> | while read -r n; do  echo "$n"done