Reputation: 3265
I have JSON such as:
{ "message": "hi" }
But it can also be of the format:
{ "message": { "action": "foo" } }
I want to filter out any records where the message.action == "foo" IF message.action even exists.
If I use the command:
jq 'select(.message.action? == null or .message.action? != "foo" )'
Then I get zero results. This appears to be because once you check for action, it then filters out any messages that are not objects, but I still want to be able to display { message: "hi" }
Upvotes: 0
Views: 271
Reputation: 531798
You can use the alternative operator //
to provide a default value for action
when it does not exist (whether because it is missing or because the value is not an object in the first place):
jq 'select((.message.action? // "foo") != "foo")'
This will accept either {"message": "hi"}
or {"message": {"action": "not foo"}}
, but not {"message": {"action": "foo"}}
.
Upvotes: 0
Reputation: 50785
Check if message points to an object which has the key action whose value is foo instead, and take logical complement of the result. There's no harm in typing a few more letters.
select(.message | type == "object" and has("action") and .action == "foo" | not)
Upvotes: 2