如何判断jq过滤器是否成功从JSON数据结构中提取数据?

Ste*_*ige 10 bash json return-code jq

我想知道给定的过滤器是否成功从JSON数据结构中提取数据.例如:

###### 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
Run Code Online (Sandbox Code Playgroud)

注意:成功的结果可以包括布尔值,null甚至是空字符串.

###### 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
Run Code Online (Sandbox Code Playgroud)

如果过滤器不从JSON数据结构中提取数据,我需要知道这一点.我希望过滤器返回非零返回码.

我如何确定选择器是否成功从JSON数据结构中提取数据而无法提取数据?

重要提示:上面的过滤器只是一个示例,解决方案需要适用于任何jq过滤器.

注意:评估环境是Bash 4.2+.

Ini*_*ian 10

您可以使用-e / --exit-status来自的标志jq Manual,表示

如果最后一个输出值既不是false也不是null,则将jq的退出状态设置为0;如果最后一个输出值为false或null,则将jq的退出状态设置为0;如果没有生成有效结果,则将4的退出状态设置为4.通常,如果存在任何使用问题或系统错误,jq将退出2;如果存在jq程序编译错误,则退出3;如果运行jq程序,则退出0.

我可以使用基本过滤器演示如下用法,因为您给出的示例对我不起作用.

要成功查询,

dudeOnMac:~$ jq -e '.foo?' <<< '{"foo": 42, "bar": "less interesting data"}'
42
dudeOnMac:~$ echo $?
0
Run Code Online (Sandbox Code Playgroud)

对于无效查询,使用不存在的实体完成zoo,

dudeOnMac:~$ jq -e '.zoo?' <<< '{"foo": 42, "bar": "less interesting data"}'
null
dudeOnMac:~$ echo $?
1
Run Code Online (Sandbox Code Playgroud)

对于错误场景,返回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
Run Code Online (Sandbox Code Playgroud)


Ste*_*ige 3

我找到了满足我所有要求的解决方案!请让我知道你在想什么!

这个想法是用作jq -e "$Filter"首次检查。然后对返回码1进行检查jq "path($Filter)"。后者只有在确实存在通往 JSON 数据的路径时才会成功。

选择.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"
Run Code Online (Sandbox Code Playgroud)

以及上面的执行:

% ./Select.sh
0 false
0 true
0 null
0 ""
4 ***ERROR***
Run Code Online (Sandbox Code Playgroud)