I have been using jq for quite a while, but some behaviour today has surprised me:
I expected this:
echo '{"Name":"NAME","Tags":[{"Key":"KEY","Value":"HASH"}]}' \
| jq '{"name": .Name, "hash": (.Tags[]|select(.Key=="hash")|.Value)}'
to produce this:
{
"name": "NAME",
"hash": null
}
but instead, it filters out the entire object from the output completely.
As a sanity check changing the filter to a value that does match as follows::
echo '{"Name":"NAME","Tags":[{"Key":"KEY","Value":"HASH"}]}' \
| jq '{"name": .Name, "hash": (.Tags[]|select(.Key=="KEY")|.Value)}'
produces the expected output:
{
"name": "NAME",
"hash": "HASH"
}
The output of the first case, select(.Key=="hash")
, is surprising to me since the select filter is meant to be acting on the stream produced by .Tags[] and not the entire input stream.
How do I express what I want to express, which is if there is no matching Tag, the "hash" property of the output object should be set to null?
I am using jq 1.6 on OSX
If a part of a filter produces empty
, it will suck in everything that is compund to it.
Solution: Don't let it produce empty
. One way would be to give the select
filter an alternative: select(.Key=="hash") // null
jq '{"name": .Name, "hash": (.Tags[] | select(.Key=="hash") // null | .Value)}'
{
"name": "NAME",
"hash": null
}