jq - jq - 返回所有具有匹配条件的子属性的顶级属性键
问题描述
我的 JSON 看起来像:
{
"foo": {
"restricted": true
},
"bar": {
"restricted": false
},
"baz": { }
}
作为单行:
{"foo":{"restricted":true},"bar":{"restricted":false},"baz":{}}
restricted == false
我想返回所有具有或不具有子属性的顶级属性键restricted
。对于上面的 JSON 示例,预期的输出是:
"bar"
"baz"
解决方案
我想出了以下表达式:
jq "to_entries[] | select(.value.restricted|not) | .key"
to_entries
将顶级对象转换为一个对象数组,每个对象具有一个"key"
和一个"value"
属性:
[
{
"key": "foo135",
"value": {
"restricted": true
}
},
{
"key": "foo246",
"value": {
"restricted": false
}
},
{
"key": "foo345",
"value": {}
}
]
[]
爆炸这个数组。这样做是为了在下一步过滤单个对象:
{
"key": "foo135",
"value": {
"restricted": true
}
}
{
"key": "foo246",
"value": {
"restricted": false
}
}
{
"key": "foo345",
"value": {}
}
然后为每个对象应用一个过滤器:select(.value.restricted|not)
. 要过滤掉子属性为真的属性restricted
,.value.restricted
可以使用单个条件反转|not
以选择具有和不具有此属性的对象:restricted == false
{
"key": "foo246",
"value": {
"restricted": false
}
}
{
"key": "foo345",
"value": {}
}
最后"key"
选择属性:.key
. 这将返回匹配对象的名称(最初是顶级属性键):
"foo246"
"foo345"
请注意,并非严格需要管道|
字符select(...) | .key
。结果是一样的。
如果需要一个字符串数组作为结果......
[
"foo246",
"foo345"
]
...然后可以使用以下表达式:
jq "to_entries | map(select(.value.restricted|not).key)"
如您所见,select()
可以使用 inside ofmap()
来过滤掉单个元素,甚至可以与属性 filter 结合使用.key
。
如果你[]
在末尾追加 like map(...)[]
,那么数组会被分解,结果又是一个字符串列表,就像在最初的示例中一样,但使用的方法略有不同。
推荐阅读
- linux - 检查 System V 共享内存段是否由大页面或常规页面支持
- php - 在 WooCommerce 3+ 中在订单状态完成操作挂钩上创建用户
- python - 我无法使用 selenium 选择/输入数据到文本区域
- java - 将 JSON 转换为单个 Bean
- tdd - TDD:在新类中重构
- jquery - 在 iframe 中使用来自 window.top 的 jquery
- json - 使用 Node.js 在 json-server 中自定义路由
- angular - 类型“SharedArrayBuffer”不可分配给类型“ArrayBuffer”
- javascript - 有没有办法以编程方式引用 Handlebars 内联部分?
- python - 从 cmd Python 运行 Anaconda 环境