使用 jq 验证根级元素的存在

Lit*_*ode 2 bash json jq

给定如下的 JSON 结构,我想测试sys/顶级密钥是否存在。

{                                                                                                                                                             
  "abc/": {                                                                                                                                             
    "uuid": "fd"
   },
 "sys/": {                                                                                                                                                   
    "uuid": "id2"
  }
}
Run Code Online (Sandbox Code Playgroud)

我尝试了各种构造,例如jq "sys/"orjq "sys/.uuid"但我得到编译错误和/或错误,例如“jq:error:sys/0 is not defined at , line 1:”

请注意,正确返回结果代码 ( $?)jq以反映实际结果非常重要(因为这是在配置管理测试中使用的)。

Ini*_*ian 5

您只需要使用has根据提到的键的存在返回布尔值的属性

jq 'has("sys/")'
Run Code Online (Sandbox Code Playgroud)

请注意,您可以自定义jq以返回 bool 字符串甚至null,但它们都不能直接用于仅使用退出代码01.

如果您希望jq在 shell 条件语句中使用的结果,您可以使其返回退出代码。有一个选项支持这一点。从文档

-e / --exit-status:

设置的退出状态jq0,如果最后的输出值既不是false也不是null1如果最后的输出值要么false或者null,或者4,如果没有有效的结果有史以来生产。

所以在你给定的 JSON 上使用它

jq -e 'has("sys/")' json > /dev/null
echo $?
0
Run Code Online (Sandbox Code Playgroud)

但是对于不存在的 key sys1,它会发出

jq -e 'has("sys1/")' json > /dev/null
echo $?
1
Run Code Online (Sandbox Code Playgroud)

请注意,> /dev/null抑制应用过滤器时抛出的标准输出,这是布尔字符串值。如果您的jq版本不支持该选项,或者您正在寻找替代方法来执行此操作,您可以直接匹配从has()过滤器返回的字符串,而不是评估退出代码,即

if [ $(jq 'has("sys/")' json) = "true" ]; then
    printf '%s\n' 'key present'
fi
Run Code Online (Sandbox Code Playgroud)