How can I determine if a jq filter is successfully retrieving data from a JSON data structure?

I want to know if this filter will be able to retrieve data from the JSON data structure. For instance:

###### 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 booleans, nulland even an 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 extract 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 decide whether a selector is successfully retrieving data from a JSON data structure or not retrieving data?

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

Note. Bash 4.2+ evaluation environment.

+4
4

, ! , , !

jq -e "$Filter" . 1 jq "path($Filter)". , JSON.

Select.sh

#!/bin/bash

Select()
{
   local Name="$1"
   local Filter="$2"
   local Input="$3"
   local Result Status

   Result="$(jq -e --arg Name "$Name" "$Filter" <<<"$Input")"
   Status=$?

   case $Status in
   1) jq --arg Name "$Name" "path($Filter)" <<<"$Input" >/dev/null 2>&1
      Status=$?
      ;;
   *) ;;
   esac

   [[ $Status -eq 0 ]] || Result="***ERROR***"
   echo "$Status $Result"
}

Filter='.[]|select(.user == $Name)|.value'
Input='[
   {"user":"steve", "value":false},
   {"user":"tom", "value":true},
   {"user":"pat", "value":null},
   {"user":"jane", "value":""}
]'

Select steve "$Filter" "$Input"
Select tom   "$Filter" "$Input"
Select pat   "$Filter" "$Input"
Select jane  "$Filter" "$Input"
Select mary  "$Filter" "$Input"

:

% ./Select.sh
0 false
0 true
0 null
0 ""
4 ***ERROR***
+1

-e / --exit-status jq Manual,

jq 0, , , 1, , , 4, . jq 2, , 3, jq, 0, jq.

, , .

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

, zoo,

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

2, jq.

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
+3

, jq , , , , , , , . , .a , get("a"), , get/1 :

def get(f): if has(f) then .[f] else error("\(type) is not defined at \(f)") end;

, , . get .

+1

, .key .[key], jq - - null.

:

def lookup(k):if has(k) then .[k] else error("invalid key") end;

:

$ jq 'lookup("a")' <<<'{}' ; echo $?
jq: error (at <stdin>:1): invalid key
5

$ jq 'lookup("a")' <<<'{"a":null}' ; echo $?
null
0

lookup , , , , .


, bash jq.

#!/bin/bash

lib='def value(f):((f|tojson)//error("no such value"))|fromjson;'

users=( steve tom pat jane mary )

Select () {
  local name=$1 filter=$2 input=$3
  local -i status=0
  result=$( jq --arg name "$name" "${lib}value(${filter})" <<<$input  2>/dev/null )
  status=$? 
  (( status )) && result="***ERROR***"
  printf '%s\t%d %s\n' "$name" $status "$result"
}

filter='.[]|select(.user == $name)|.value'

input='[{"user":"steve","value":false},
        {"user":"tom","value":true},
        {"user":"pat","value":null},
        {"user":"jane","value":""}]'

for name in "${users[@]}"
do
  Select "$name" "$filter" "$input"
done

:

steve   0 false
tom     0 true
pat     0 null
jane    0 ""
mary    5 ***ERROR***

, empty, //, - "null" "false" - .

It should be noted that the value/1search for objects / arrays will not work for filters that are simple keys / indexes, but your solution will not. I'm pretty sure that cover all cases, you will need something like this (or yours) and  for example getor lookup.

0
source

Source: https://habr.com/ru/post/1663641/


All Articles