JQ - Handling null values and default values
When working with JSON data using jq
, handling null values, missing keys, nested fields, and default values is crucial for writing robust scripts. In this post, we'll explore how to manage these cases effectively.
Handling Null Values in JSON Input
When a JSON field contains a null
value, jq
treats it as null
. You can use the //
operator to provide a default value in such cases. In the following example, we check for a null
value and provide a default:
jq '.age // 18' input.json
Given an input JSON like this:
{
"name": "Alice",
"age": null
}
If .age
is null, the output will be 18
; otherwise, it will return the actual value.
Handling Absent Keys
If a key is not present in the JSON input, jq
will return null
when accessing it.
To avoid unexpected null results, you can check for the presence of a key using the has function.
Here's how you can provide a default value when a key is absent:
jq 'if has("age") then .age else 18 end' input.json
Given an input JSON like this:
{
"name": "Alice"
}
This expression checks if the "age" key exists. If it does, it returns the value; otherwise, it defaults to 18.
Handling Nested Fields
When working with nested fields, both the parent and child fields may be missing or null
. Combining the ?.
operator with the //
operator allows handling these cases gracefully.
In the following example, we handle the scenario where nested fields may be missing:
jq '.user?.details?.age // 18' input.json
Given an input JSON like this:
{
"user": {
"details": {
"name": "Alice"
}
}
}
If .user
, .user.details
, or .user.details.age
is null or does not exist, the expression defaults to 18
.
Providing Default Values Based on Data Type
You might want to set default values based on the expected type of a field (e.g., string
, integer
, boolean
).
The jq
conditionals allow you to specify defaults for different data types. In the following example, we provide defaults for multiple types:
jq '{
name: .name // "Unknown",
age: .age // 0,
active: .active // false
}' input.json
Given an input JSON like this:
{
"name": null,
"age": null,
"active": null
}
This expression sets "Unknown" for strings, 0
for integers, and false
for booleans if the original values are null.
Nested Defaults with Multiple Levels
Handling multiple levels of nested fields may require combining several techniques. Here, we demonstrate handling missing or null values in deeply nested fields using both the // operator and conditional expressions:
jq '.user.details.address // "No address provided"' input.json
Given an input JSON like this:
{
"user": {
"details": {
"address": null
}
}
}
If .user.details.address
is null or missing, the output will be "No address provided".