首页 > 解决方案 > 使用 jq 验证根级元素的存在

问题描述

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

{                                                                                                                                                             
  "abc/": {                                                                                                                                             
    "uuid": "fd"
   },
 "sys/": {                                                                                                                                                   
    "uuid": "id2"
  }
}

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

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

标签: jsonbashjq

解决方案


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

jq 'has("sys/")'

请注意,您可以自定义返回booljq字符串甚至.null01

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

-e / --exit-status:

如果最后一个输出值不是or ,如果最后一个输出值是or ,或者没有产生有效结果,则将退出状态设置为jq0falsenull1falsenull4

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

jq -e 'has("sys/")' json > /dev/null
echo $?
0

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

jq -e 'has("sys1/")' json > /dev/null
echo $?
1

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

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

推荐阅读