How can I tell if a jq filter successfully pulls data from a JSON data structure?

Steve Amerige picture Steve Amerige · Dec 13, 2016 · Viewed 12.9k times · Source

I want to know if a given filter succeeds in pulling data from a JSON data structure. For example:

###### For the user steve...

% Name=steve
% jq -j --arg Name "$Name" '.[]|select(.user == $Name)|.value' <<<'
[
   {"user":"steve", "value":false},
   {"user":"tom", "value":true},
   {"user":"pat", "value":null},
   {"user":"jane", "value":""}
]'
false
% echo $?
0

Note: successful results can include boolean values, null, and even the empty string.

###### Now for user not in the JSON data...

% Name=mary
% jq -j --arg Name "$Name" '.[]|select(.user == $Name)|.value' <<<'
[
   {"user":"steve", "value":false},
   {"user":"tom", "value":true},
   {"user":"pat", "value":null},
   {"user":"jane", "value":""}
]'
% echo $?
0

If the filter does not pull data from the JSON data structure, I need to know this. I would prefer the filter to return a non-zero return code.

How would I go about determining if a selector successfully pulls data from a JSON data structure vs. fails to pull data?

Important: The above filter is just an example, the solution needs to work for any jq filter.

Note: the evaluation environment is Bash 4.2+.

Answer

Inian picture Inian · Dec 13, 2016

You can use the -e / --exit-status flag from the jq Manual, which says

Sets the exit status of jq to 0 if the last output values was neither false nor null, 1 if the last output value was either false or null, or 4 if no valid result was ever produced. Normally jq exits with 2 if there was any usage problem or system error, 3 if there was a jq program compile error, or 0 if the jq program ran.

I can demonstrate the usage with a basic filter as below, as your given example is not working for me.

For a successful query,

dudeOnMac:~$ jq -e '.foo?' <<< '{"foo": 42, "bar": "less interesting data"}'
42
dudeOnMac:~$ echo $?
0

For an invalid query, done with a non-existent entity zoo,

dudeOnMac:~$ jq -e '.zoo?' <<< '{"foo": 42, "bar": "less interesting data"}'
null
dudeOnMac:~$ echo $?
1

For an error scenario, returning code 2 which I created by double-quoting the jq input stream.

dudeOnMac:~$ jq -e '.zoo?' <<< "{"foo": 42, "bar": "less interesting data"}"
jq: error: Could not open file interesting: No such file or directory
jq: error: Could not open file data}: No such file or directory
dudeOnMac:~$ echo $?
2