jq 过滤内部数组元素但返回整个 JSON
Posted
技术标签:
【中文标题】jq 过滤内部数组元素但返回整个 JSON【英文标题】:jq to filter inner array elements but return the whole JSON 【发布时间】:2020-07-10 18:02:47 【问题描述】:TL;DR
过滤***键的内部数组元素后如何返回整个 JSON?
详细解释
我有一个描述 COCO 图像数据库的 JSON,它的格式如下(不相关的元素被截断为 ...
)。
"info":
"description": "COCO 2017 Dataset",
...
,
"licenses": [
"url": "http://creativecommons.org/licenses/by-nc-sa/2.0/",
...
,
...
],
"images": [
"license": 4,
...
,
"annotations": [
"segmentation": [
[
510.66,
...
]
],
"area": 702.1057499999998,
"iscrowd": 0,
"image_id": 289343,
"bbox": [
473.07,
395.93,
38.65,
28.67
],
"category_id": 18,
"id": 1768
,
"categories": [
"supercategory": "person",
...
,
]
我需要过滤annotations
,其中category_id
具有多个值之一,例如1, 2
。
我可以成功过滤这样的category_id
s
jq -C ' .annotations[] | select( .category_id == 1 or .category_id == 2 ) ' instances_val2017.json | less -R
但是,返回的只是整个 JSON 的 annotations 元素,如下所示。
"segmentation": [
[
162.72,
...
]
],
"area": 426.9120499999995,
"iscrowd": 0,
"image_id": 45596,
"bbox": [
161.52,
507.18,
46.45,
19.16
],
"category_id": 2,
"id": 124742
...
我知道可以通过将表达式包装在 []
中来将这些元素作为数组返回,但是如何在过滤指定的类别 ID 后返回整个原始 JSON?
【问题讨论】:
【参考方案1】:好吧,我昨天花了 3 个小时试图解决这个问题,然后今天早上我发布了这个问题,随后想通了!
这里是使用|=
操作符的解决方案,它可以修改元素。
jq '.annotations |= map(select(.category_id | contains(1,2)))' instances_val2017.json
根据@peak 的建议,这里是用==
代替contains
的命令。
jq '.annotations |= map(select(.category_id == (1,2)))' instances_val2017.json
【讨论】:
contains
语义非常复杂,很容易产生“意外结果”。它也可能很慢。在这种特殊情况下,您可以简单地写map(select(.category_id == (1,2)))
。一般来说,index
(小写)和IN
(大写)也值得考虑。以上是关于jq 过滤内部数组元素但返回整个 JSON的主要内容,如果未能解决你的问题,请参考以下文章