JSON Tools: Jq

grammar and invocation | variables and expressions | arithmetic and logic | strings | regular expressions | dates and time | arrays | dictionaries | functions | execution control | exceptions | streams | file formats | processes and environment | libraries and namespaces | reflection

version
jq
version used
 
1.5
show version
 
$ jq --version
grammar and execution
jq
interpreter $ cat > hello.jq
"Hello, World!"

# -n: use single "null" as input
# -r: write string content instead of quoted string literal to stdout

$ jq -nr -f hello.jq
Hello, World!
command line program $ echo '1 2 3' | jq '. * .'

# no stdin:
$ jq -n '1 + 1'
statement separator A program consists of filter expressions separated by commas and pipes: , |

A filter expressions acts on its input and produces output.

The pipe separator makes the output of the left expression the input of the right expression.

The comma separator, which concatenates the output of two filters, has higher precedence than the pipe separator.

A function definition, include statement, or import statement is terminated by a semicolon: ;
block delimiters
 
# Use parens to change precedence:
$ jq -n '2, (3 | . * .)'
$ jq -n '2, 3 | . * .'
end of line comment
 
# comment
variables and expressions
jq
assignment $ echo '[1,2,3]' | jq 'length as $x | map(. * $x)'

"length as $x" assigns the value 3 to $x.

The following filter receives the same input the assignment filter got.
compound assignment |= += -= *= /= %= //=

Compound operators are used with arrays and dictionaries. A copy of the array or dictionary is returned, with fields specified on the LHS replaced by new values. If the compound assignment expression is "LHS OP= RHS", then the new value is "LHS OP RHS".

# {"t": 2, "f": 0}:
$ echo '{"t": 1, "f": 0}' | jq '.t += 1'

More than one field can be updated.

# {"t": 2, "f": 1}:

$ echo '{"t": 1, "f": 0}' | jq '.[] += 1'
null
 
null
null test
 
$ echo '{"name": "Ed"}' | jq '.age == null'
coalesce # also replaces false:
$ echo '{}' | jq '.age // 0'
conditional expression
 
$ echo '-3' | jq 'if . < 0 then -. else . end'
arithmetic and logic
jq
true and false
 
true false
falsehoods
 
null false
logical operators
 
and or not
relational operators
 
== != < > <= >=
min and max
 
$ echo '[1,2,3]' | jq 'min'
$ echo '[1,2,3]' | jq 'max'
arithmetic operators
 
+ - * / %
integer division # floor is new in 1.4:
$ jq -n '-13 / 5 | floor'
division by zero
 
error
sqrt # new in 1.4:
$ jq -n '2 | sqrt'
sqrt -1 # null:
$ jq -n '-1 | sqrt'
transcendental functions # new in 1.5:
exp log
sin cos tan
asin acos atan
float truncation # floor is new in 1.4:
$ jq '1.1 | floor'
strings
jq
literal
 
"lorem ipsum"
newline in literal
 
not allowed; use \n escape sequence
string escapes
 
\\ \" \/ \b \f \n \r \r \t \uhhhh
variable interpolation
 
$ echo '{"foo": 1, "bar": 2}' | jq '"\(.foo):\(.bar)"'
concatenate
 
"foo" + "bar"
translate case $ echo '"foo"' | jq 'ascii_upcase
$ echo '"FOO"' | jq 'ascii_downcase'
number to string
 
$ echo '7' | jq 'tostring'
string to number
 
$ echo '"7"' | jq 'tonumber'
string join # join is new in 1.4:
$ echo '["do", "re", "mi"]' | jq 'join(" ")'
split # split is new in 1.4:
$ echo '"do re mi"' | jq 'split(" ")'

# remove two empty strings:
$ echo '" do re mi"' | jq 'split(" ") | map(select(length > 0))'
prefix and suffix test $ echo '"foobar"' | jq 'startswith("foo")'
$ echo '"foobar"' | jq 'endswith("bar")'
string length
 
$ jq -R 'length' /etc/hosts
index of substring

first, last
# 3:
$ echo '"do re re"' | jq 'index("re")'

# 6:
$ echo '"do re re"' | jq 'rindex("re")'

# null:
$ echo '"do re re"' | jq 'rindex("mi")'
regular expressions
jq
literal # regexes are new in 1.5:
"lorem|ipsum"
character class abbrevations but backslashes must be doubled inside double quotes:
. \d \D \h \H \s \S \w \W
anchors but backslashes must be doubled inside double quotes:
^ $ \A \b \B \z \Z
match test
 
$ echo $'"It\'s 1999!"' | jq '. | test("1999")'
case insensitive match test $ echo $'"FOO BAR"' | jq 'test("foo"; "i")'
$ echo $'"FOO BAR"' | jq 'test(["foo", "i"])'
$ echo $'"FOO BAR"' | jq 'test("(?i)foo")'
substitution

first occurrence, all occurrences
$ echo '"do re mi mi mi"' | jq 'sub("mi"; "ma")'
$ echo '"do re mi mi mi"' | jq 'gsub("mi"; "ma")'
named group capture
 
$ echo '"foo.txt"' | jq 'capture("^(?<root>.*)\\.(?<suffix>.*)$") | .root'
dates and time
jq
current datetime # date/time functions are new in 1.5

# array of broken-down datetime values:
$ jq -n 'now | gmtime'

# ISO 8601 format:
$ jq -n 'now | gmtime | todate'
current unix epoch
 
$ jq -n 'now'
broken-down datetime to unix epoch $ echo '[2016,11,15,11,30,0,4,349]' | jq 'mktime'
unix epoch to broken-down datetime $ echo 1481801400 | jq 'gmtime'
format datetime
 
$ jq -n 'now | gmtime | strftime("%Y-%m-%d %H:%M:%S")'
parse datetime # parses to array of broken-down datetime values:
$ echo '"2016-12-15 11:30:00"' | jq 'strptime("%Y-%m-%d %H:%M:%S")'
arrays
jq
lookup # 6:
$ echo '[6, 7, 8, 9'] | jq '.[0]'
not an array behavior # error:
$ echo 1 | jq '.[0]'

# no error and no output:
$ echo 1 | jq '.[0]?'
length $ echo '[6, 7, 8, 9'] | jq 'length'
slice # [7, 8]:
$ echo '[6,7,8,9]' | jq '.[1:3]'
slice from beginning $ jq -c '.[:2]'
slice to end from element 3 on:
$ jq -c '.[2:]'

last two elements:
$ jq -c '.[-2:]'
indices $ jq -c 'keys'
reverse $ echo '[1,2,3]' | jq 'reverse'
sort $ echo '[3,1,4,2]' | jq 'sort'
dedupe $ echo '[1,1,2,3]' | jq 'unique'
subset test $ echo '[1,2,3]' | jq 'contains([1])'
$ echo '[1]' | jq 'inside([1,2,3])'
map $ echo '[1,2,3]' | jq '.[] | . * .'
$ echo '[1,2,3]' | jq 'map(. * .)'
filter $ echo '[1,2,3]' | jq 'map(select(. > 2))'
reduce $ echo '[1,2,3,4]'| jq 'reduce .[] as $item (0; .+$item)'
universal and existential test $ echo '[1,2,3]' | jq 'all(. > 2)'
$ echo '[1,2,3]' | jq 'any(. > 2)'
flatten
one level, completely
# flatten is new in 1.5:
$ echo '[1,[2,[3]]]' | jq -c 'flatten(1)'
$ echo '[1,[2,[3]]]' | jq -c 'flatten'
dictionaries
jq
literal {"t": 1, "f": 0}
size $ echo '{"t": 1, "f": 0}' | jq 'length'
lookup $ echo '{"t": 1, "f": 0}' | jq '.t'
$ echo '{"t": 1, "f": 0}' | jq '.["t"]'
update $ echo '{"t": 1, "f": 0}' | jq '.f = -1'
is key present $ echo '{"t": 1, "f": 0}' | jq 'has("t")'
$ echo '"t"' | jq 'in({"t": 1, "f": 0})'
missing key behavior # null:
$ echo '{"t": 1, "f": 0}' | jq '.m'
not a dictionary behavior # error:
$ echo 1 | jq '.foo'

# no error and no output:
$ echo 1 | jq '.foo?'
delete $ echo '{"t": 1, "f": 0}' | jq 'del(.t)'
keys and values as arrays $ echo '{"do": 1, "re": 2}' | jq 'keys'
$ echo '{"do": 1, "re": 2}' | jq 'to_entries | map(.value)'
functions
jq
define $ echo '1 2 3 4' | jq 'def double: 2 * .;'
call $ echo '1 2 3 4' | jq 'def double: 2 * .; double'
function with argument $ echo '1 2 3 4' | jq 'def multiply($x): . * $x; multiply(7)'

# without $, argument is treated as a filter:
echo '1 2 3 4' | jq 'def apply(f): f; apply(. * 7)'
execution control
jq
if $ echo '-3' | jq 'if . < 0 then -. else . end'
while $ jq -n '1 | while(. < 10; . + 1)'
break $ jq -n '1 | label $out | while(true; if . > 10 then break $out else. + 1 end)'
exceptions
jq
raise exception $ jq -n 'error("bam!")'
handle exception # set output to null:
$ jq -n 'try error("bam!") catch null'

# two ways to handle with no output:
$ jq -n 'try error("bam!") catch empty'
$ jq -n 'error("bam!")?'
streams
jq
write to stderr # input to debug is also passed on to subsequent filters:
$ jq -n '"foo" | debug'
read input as array of strings $ jq -R 'length' /etc/hosts
array to stream $ echo '[1,2,3]' | jq '.[]'
stream to array $ echo '1 2 3' | jq -s '.'
file formats
jq
processes and environment
jq
environment variable $ jq -n 'env.HOME'
$ jq -n 'env["HOME"]'
libraries and namespaces
jq
load library $ cat > multiples.jq
def double: 2 * .;
def triple: 3 * .;
def quadruple; 4 * .;

$ echo 3 | jq 'include "multiples"; double'
library path command line option $ mkdir ~/.jq
$ cat > ~/.jq/multiples.jq
def double: 2 * .;
def triple: 3 * .;
def quadruple; 4 * .;

$ echo 3 | jq -L ~/.jq 'include "multiples"; double'
load definitions in namespace $ cat > multiples.jq
def double: 2 * .;
def triple: 3 * .;
def quadruple; 4 * .;

$ echo 3 | jq 'import "multiples" as mult; mult::double'
reflection
jq
inspect type $ echo '{"foo": 1}' | jq '.foo | type'
basic types "number"
"boolean"
"array"
"object"
"null"
"string"
___________________________________________________________________

Jq

jq man page

issue tracker | content of this page licensed under creative commons attribution-sharealike 3.0