如何使用jq修改符合过滤条件的子对象属性值?
用jq修改数组中匹配条件的子对象属性值
需求说明
需要修改数组里第一个满足Action.Charge非零的对象,将该属性值改为34。对应的JavaScript参考实现如下:
list.map(z => {if (z.Action.Charge > 0) { z.Action.Charge = 1;} return z;})
尝试的无效代码
我尝试用jq实现,但写出的代码没有效果:
cat list | jq '.values = .values | if ( .value.Action.Charge == 0 ) then ( .value.Action.Charge = 1 ) else . end'
输入JSON数据
[ { "Action": { "Charge": 21, "Discharge": 100 }, "T": "2023-10-05T01:00:00Z" }, { "Action": { "Charge": 0, "Discharge": 22 }, "T": "2023-10-05T04:00:00Z" } ]
期望输出结果
[ { "Action": { "Charge": 34, "Discharge": 100 }, "T": "2023-10-05T01:00:00Z" }, { "Action": { "Charge": 0, "Discharge": 22 }, "T": "2023-10-05T04:00:00Z" } ]
正确解决方案
可行的jq命令
有两种简洁的实现方式:
方式一:遍历数组,仅修改第一个匹配条件的元素
jq 'map(if .Action.Charge != 0 and (index($$) == 0) then .Action.Charge = 34 else . end)' list
方式二:直接定位到第一个匹配的元素修改属性
jq '(.[] | select(.Action.Charge != 0))[0].Action.Charge = 34' list
原代码无效的原因
- 输入JSON是一个直接的数组,不存在
.values或.value字段,原代码引用了错误的路径; - 条件判断逻辑和需求不符,原代码判断的是
Charge == 0时修改,而需求是修改非零的项; - 没有限制只修改第一个匹配的元素。
内容的提问来源于stack exchange,提问作者Richard Barraclough
相关产品推荐
相关产品推荐

