如何利用Bash变量中的JSON数据更新deployment.json的subPath字段?
问题分析与解决方案
原命令的问题
你的实现方式不可行,核心问题有两点:
- JSON数据传递错误:使用
--arg会把$services里的JSON数组当作普通字符串传入jq,导致jq无法解析成JSON结构进行后续匹配操作,必须用--argjson来传递JSON类型的数据。 - 表达式逻辑与语法错误:
- 引用的
.key在deployment.json的volumeMounts项中不存在,匹配逻辑完全错误; - 对象构造语法混乱,
{ mountPath: .mountPath, name: (.key, subPath: ...) }不符合jq语法规则,会生成无效的JSON结构。
- 引用的
正确实现方法
核心思路:通过volumeMounts里的name字段,匹配$services数组中对应的cm字段,找到对应项的subPath后替换原有值。
正确命令
jq --argjson services "$services" \ '.spec.template.spec.containers[].volumeMounts[]? |= ( .name as $currentName | .subPath = ($services | .[] | select(.cm == $currentName).subPath) )' deployment.json
命令细节解释
--argjson services "$services":将Bash变量$services中的JSON数组以JSON类型传入jq,确保jq能正常解析处理。.spec.template.spec.containers[].volumeMounts[]?:遍历所有容器下的volumeMounts项,?符号用于忽略不存在volumeMounts的容器,避免执行报错。.name as $currentName:将当前volumeMounts项的name值暂存为变量,方便后续匹配$services中的cm字段。($services | .[] | select(.cm == $currentName).subPath):遍历$services数组,筛选出cm字段与当前volumeMounts的name匹配的项,取出其subPath值。.subPath = ...:将当前volumeMounts项的subPath替换为匹配到的新值。
执行效果
执行命令后,deployment.json中volumeMounts的subPath会被替换为$services数组中对应cm项的subPath值;若后续修改$services中的数据,重新执行命令即可同步更新。
内容的提问来源于stack exchange,提问作者Nathanaël Blanchet
相关产品推荐
相关产品推荐

