我有一个来自API的JSON对象,如下所示:
{
"objectList": [
{
"name": "item1",
"value": false
},
{
"name": "item2",
"value": true
}
]
}
我需要在此附加项目。我可以使用jq
:
jq '.objectList += [{"name": "item3", "value": true}]' apiResponse.json
但是,有时我需要添加一个带有name属性的项目,该属性已存在于响应中,我需要使用我想要设置的新值来覆盖它的值。例如,我可能想要更改' item2'的值。到false
。
我已经在jq中编写了一个过滤器,以便我可以遍历objectList
,但我不确定如何比较两个名称(我要添加的名称,以及循环的当前迭代中的项的名称)。这是我的循环过滤器:
jq -r '.objectList[] | [.name]
这会打印出如下数组:
[
"extendedStatus"
]
[
"anotherFeature"
]
然后我尝试在这个过滤器上添加一个条件:
jq -r '.objectList[] | if .name == "item1" then .value == true else .value == false end' apiResponse.json
但这只是打印出来的:
true
false
编辑 - 略微改进的过滤器:
jq -r '.objectList[] | if .name == "item1" then {name: .name, value: true} else {name: .name, value: false} end'
打印出来:
{
"name": "item1",
"value": true
}
{
"name": "item2",
"value": false
}
这种改进的过滤器效果更好,但是如果项目中没有项目(当它完成循环时),我仍然不确定如何添加项目。
有一点需要注意 - 这是在一个bash脚本中完成的,在一个方法中我有参数(项目的名称和值)。
答案 0 :(得分:0)
让我们说主要的API json文件apiResponse.json
:
{
"objectList": [
{
"name": "item1",
"value": false
},
{
"name": "item2",
"value": true
},
{
"name": "item4",
"value": true
}
]
}
我们有文件new_objects.dat
中包含的新对象列表:
{"name":"item1","value":true}
{"name":"item2","value":false}
{"name":"item3","value":true}
jq --slurpfile new_items new_objects.dat \
'.objectList |= [ . + $new_items | group_by(.name)[] | add ]' apiResponse.json
输出:
{
"objectList": [
{
"name": "item1",
"value": true
},
{
"name": "item2",
"value": false
},
{
"name": "item3",
"value": true
},
{
"name": "item4",
"value": true
}
]
}
答案 1 :(得分:0)
您可以使用select
过滤输入。这将选择“item2”元素:
.objectList[] | select(.name == "item2")
如果选择“item3”,上面的内容将返回null
。在这种情况下,您可以使用替代运算符//
来定义默认值:
(.objectList[] | select(.name == "itemX")) // {"name": "item3", "value": null}
以上将始终返回一个对象,可以通过将“value”设置为false
来修改该对象:
((.objectList[] | select(.name == "itemX")) // {"name": "item3", "value": null}) | .value = false
为了获得完整列表,您必须添加与另一个选择不匹配的元素。
.objectList[] | select(.name != "itemX")
可以使用逗号和方括号连接两个列表,并将结果放入新对象中。
[
(((.objectList[] | select(.name == "itemX")) // {"name": "item3", "value": null}) | .value = false)
,
(.objectList[] | select(.name != "itemX"))
] |
{"objectList": .}