On this page

Conditionals and Comparisons

==, !=

The expression 'a == b' will produce 'true' if the results of evaluating a and b are equal (that is, if they represent equivalent JSON values) and 'false' otherwise. In particular, strings are never considered equal to numbers. In checking for the equality of JSON objects, the ordering of keys is irrelevant. If you're coming from JavaScript, please note that jq's == is like JavaScript's ===, the "strict equality" operator.

!= is "not equal", and 'a != b' returns the opposite value of 'a == b'

Example 1

Command

jq '. == false'

Input

null

Output 1

false

Example 2

Command

jq '. == {"b": {"d": (4 + 1e-20), "c": 3}, "a":1}'

Input

{"a":1, "b": {"c": 3, "d": 4}}

Output 1

true

Example 3

Command

jq '.[] == 1'

Input

[1, 1.0, "1", "banana"]

Output 1

true

Output 2

true

Output 3

false

Output 4

false

if-then-else-end

if A then B else C end will act the same as B if A produces a value other than false or null, but act the same as C otherwise.

if A then B end is the same as if A then B else . end. That is, the else branch is optional, and if absent is the same as .. This also applies to elif with absent ending else branch.

Checking for false or null is a simpler notion of "truthiness" than is found in JavaScript or Python, but it means that you'll sometimes have to be more explicit about the condition you want. You can't test whether, e.g. a string is empty using if .name then A else B end; you'll need something like if .name == "" then A else B end instead.

If the condition A produces multiple results, then B is evaluated once for each result that is not false or null, and C is evaluated once for each false or null.

More cases can be added to an if using elif A then B syntax.

Example 1

Command

jq 'if . == 0 then
  "zero"
elif . == 1 then
  "one"
else
  "many"
end'

Input

2

Output 1

"many"

>, >=, <=, <

The comparison operators >, >=, <=, < return whether their left argument is greater than, greater than or equal to, less than or equal to or less than their right argument (respectively).

The ordering is the same as that described for sort, above.

Example 1

Command

jq '. < 5'

Input

2

Output 1

true

and, or, not

jq supports the normal Boolean operators and, or, not. They have the same standard of truth as if expressions - false and null are considered "false values", and anything else is a "true value".

If an operand of one of these operators produces multiple results, the operator itself will produce a result for each input.

not is in fact a builtin function rather than an operator, so it is called as a filter to which things can be piped rather than with special syntax, as in .foo and .bar | not.

These three only produce the values true and false, and so are only useful for genuine Boolean operations, rather than the common Perl/Python/Ruby idiom of "value_that_may_be_null or default". If you want to use this form of "or", picking between two values rather than evaluating a condition, see the // operator below.

Example 1

Command

jq '42 and "a string"'

Input

null

Output 1

true

Example 2

Command

jq '(true, false) or false'

Input

null

Output 1

true

Output 2

false

Example 3

Command

jq '(true, true) and (true, false)'

Input

null

Output 1

true

Output 2

false

Output 3

true

Output 4

false

Example 4

Command

jq '[true, false | not]'

Input

null

Output 1

[false, true]

Alternative operator: //

The // operator produces all the values of its left-hand side that are neither false nor null. If the left-hand side produces no values other than false or null, then // produces all the values of its right-hand side.

A filter of the form a // b produces all the results of a that are not false or null. If a produces no results, or no results other than false or null, then a // b produces the results of b.

This is useful for providing defaults: .foo // 1 will evaluate to 1 if there's no .foo element in the input. It's similar to how or is sometimes used in Python (jq's or operator is reserved for strictly Boolean operations).

Note: some_generator // defaults_here is not the same as some_generator | . // defaults_here. The latter will produce default values for all non-false, non-null values of the left-hand side, while the former will not. Precedence rules can make this confusing. For example, in false, 1 // 2 the left-hand side of // is 1, not false, 1 -- false, 1 // 2 parses the same way as false, (1 // 2). In (false, null, 1) | . // 42 the left-hand side of // is ., which always produces just one value, while in (false, null, 1) // 42 the left-hand side is a generator of three values, and since it produces a value other false and null, the default 42 is not produced.

Example 1

Command

jq 'empty // 42'

Input

null

Output 1

42

Example 2

Command

jq '.foo // 42'

Input

{"foo": 19}

Output 1

19

Example 3

Command

jq '.foo // 42'

Input

{}

Output 1

42

Example 4

Command

jq '(false, null, 1) // 42'

Input

null

Output 1

1

Example 5

Command

jq '(false, null, 1) | . // 42'

Input

null

Output 1

42

Output 2

42

Output 3

1

try-catch

Errors can be caught by using try EXP catch EXP. The first expression is executed, and if it fails then the second is executed with the error message. The output of the handler, if any, is output as if it had been the output of the expression to try.

The try EXP form uses empty as the exception handler.

Example 1

Command

jq 'try .a catch ". is not an object"'

Input

true

Output 1

". is not an object"

Example 2

Command

jq '[.[]|try .a]'

Input

[{}, true, {"a":1}]

Output 1

[null, 1]

Example 3

Command

jq 'try error("some exception") catch .'

Input

true

Output 1

"some exception"

Breaking out of control structures

A convenient use of try/catch is to break out of control structures like reduce, foreach, while, and so on.

For example:

# Repeat an expression until it raises "break" as an
# error, then stop repeating without re-raising the error.
# But if the error caught is not "break" then re-raise it.
try repeat(exp) catch if .=="break" then empty else error

jq has a syntax for named lexical labels to "break" or "go (back) to":

label $out | ... break $out ...

The break $label_name expression will cause the program to act as though the nearest (to the left) label $label_name produced empty.

The relationship between the break and corresponding label is lexical: the label has to be "visible" from the break.

To break out of a reduce, for example:

label $out | reduce .[] as $item (null; if .==false then break $out else ... end)

The following jq program produces a syntax error:

break $out

because no label $out is visible.

Error Suppression / Optional Operator: ?

The ? operator, used as EXP?, is shorthand for try EXP.

Example 1

Command

jq '[.[] | .a?]'

Input

[{}, true, {"a":1}]

Output 1

[null, 1]

Example 2

Command

jq '[.[] | tonumber?]'

Input

["1", "invalid", "3", 4]

Output 1

[1, 3, 4]