如何实现列表不存在则创建,仅添加不存在元素?(jq处理JSON实操)
解决JSON中apps数组元素的dep字段统一添加"b.jar"问题
我来帮你搞定这个jq处理的问题,你需要的是对每个apps元素做精准判断,既不重复添加也不遗漏任何元素。
正确的jq命令
cat dep.json | jq '.apps |= map( if .dep == null then . + {dep: ["b.jar"]} elif (.dep | index("b.jar")) == null then .dep += ["b.jar"] else . end )'
命令逻辑拆解
我们用map遍历apps数组里的每一个元素,分三种场景处理:
- 场景1:元素无dep字段:用
. + {dep: ["b.jar"]}给元素新增dep数组并填入"b.jar" - 场景2:元素有dep数组但不含"b.jar":用
.dep += ["b.jar"]把"b.jar"追加到dep数组中 - 场景3:dep数组已包含"b.jar":直接返回原元素,不做任何修改
分析你之前的命令问题
- 盲目添加导致重复:
jq '.apps[].dep += ["b.jar"]'这个命令会无视dep数组已有内容直接追加,所以whatever3的dep会变成["a.jar", "b.jar", "b.jar"],不符合需求。 - 丢失层级且过滤元素:
jq '.apps | map(select(.dep == null or (.dep | contains(["b.jar"]) | not)))[] | .dep += ["b.jar"]'存在两个问题:- 先抽离
.apps单独处理,最终输出的是单个元素而非完整JSON结构,丢失了最外层的{ "apps": [...] }层级 select会过滤掉已包含"b.jar"的元素,导致whatever3直接被排除在结果之外,不符合要求
- 先抽离
测试验证
用你提供的输入示例运行上述命令,会得到和输出示例完全一致的结果:
{ "apps": [ { "name": "whatever1", "id": "ID1", "dep": [ "b.jar" ] }, { "name": "whatever2", "id": "ID2", "dep": [ "a.jar", "b.jar" ] }, { "name": "whatever3", "id": "ID3", "dep": [ "a.jar", "b.jar" ] } ] }
内容的提问来源于stack exchange,提问作者Dyno Fu
相关产品推荐
相关产品推荐

