如何使用jq批量替换JSON值且避免结果重复?
解决jq脚本生成多份JSON副本的问题
需求说明
需要更新JSON文件中满足以下所有条件的属性:
- 属性名称包含
Description字符串 - 属性的
ismydata属性值为true - 属性的
deprecatedVersion值为空字符串
示例JSON
{ "name": "account", "description": "Some description", "attributes": { "accountNameCode": { "description": "Name of the account type.", "type": "string", "ismydata": true, "deprecatedVersion": "" }, "accountNameDescription": { "description": "Description of the account type.", "type": "string", "ismydata": true, "deprecatedVersion": "" }, "anotherDescription": { "description": "Some other thing.", "type": "string", "ismydata": true, "deprecatedVersion": "" } } }
原脚本问题
原脚本会为每个匹配项生成一份完整的JSON副本,导致输出多份结构相同的结果:
(.attributes | with_entries( select(.key|contains("Description"))) | keys[] as $k | .[$k] | select(.ismydata==true) and select(.deprecatedVersion=="") | $k) as $matchKey | .attributes[$matchKey].description as $description | .attributes[$matchKey].deprecatedVersion |= "Y" | .attributes[$matchKey].description |= "Deprecated- this has been replaced by... " + $description
修改后的脚本
使用with_entries批量处理符合条件的属性,只输出一份修改后的完整JSON:
.attributes |= with_entries( if .key | contains("Description") and .value.ismydata == true and .value.deprecatedVersion == "" then .value |= ( .deprecatedVersion = "Y" | .description = "Deprecated- this has been replaced by... " + .description ) else . end )
脚本说明
原脚本的问题在于通过keys[] as $k遍历匹配键时,每次循环都会触发一次完整JSON的输出。修改后的脚本直接在.attributes层级上,用with_entries对每个条目进行判断:
- 检查键是否包含
Description - 检查对应值的
ismydata是否为true - 检查
deprecatedVersion是否为空字符串 - 对符合条件的条目,一次性修改
deprecatedVersion和description字段
整个过程只对原始JSON做一次批量修改,最终输出单一的完整JSON结构。
内容的提问来源于stack exchange,提问作者Timbuck
相关产品推荐
相关产品推荐

