如何使用jq批量修改JSON深层body.raw及key-value对象值?
问题:用JQ批量处理JSON的两个需求
原始JSON结构
{ "bla": { "body": { "mode": "raw", "raw": "{\n \"accountId\": \"1111\",\n \"monetaryAmount\": {\n \"amount\": 111,\n \"exponent\": 2,\n \"currency\": \"aaa\"\n },\n \"remarks\": \"consequat quis\"\n}", "options": { "raw": { "language": "json" } } } }, "auth": { "type": "bearer", "bearer": [ { "key": "token", "value": "{{token}}", "type": "string" } ] }, "segg": { "key": "txn_id", "value": "{{token}}", "type": "string" }, "slugg": { "key": "companyId", "value": "{{token}}", "type": "string" }, "blu": [ { "key": "teamMemberId", "value": "{{token}}", "type": "string" } ] }
需求
- 对任意层级的
..body.raw字符串,优先解析为JSON后用JQ操作(而非简单搜索替换); - 对任意层级包含
.key和.value的对象,将.value替换为"{{"+.key+"}}"格式。
现有JQ代码(存在问题)
del(.. | objects | .auth)|(.. | objects | select(.key == "teamMemberId")).value="{{teamMemberId}}"|(.. | objects | select(.key == "accountId")).value="{{accountId}}"|(.. | objects | select(.key == "companyId")).value="{{companyId}}"|(.. | objects | select(.key == "transactionId")).value="{{transactionId}}"|(.. | objects | select(.key == "txn_id")).value="{{transactionId}}"|(.. | objects | select(.key == "limitType")).value="MONTHLY"|(.. | objects | select(.raw | type == "string")).raw=null
现有代码无法实现..raw的解析操作,且key-value替换的写法过于冗余,需要优化。
解决方案
1. 批量处理key-value对象的替换
无需逐个匹配key,直接递归遍历所有包含.key和.value的对象,统一替换:
.. | objects | select(has("key") and has("value")) |= .value = "{{\(.key)}}"
2. 解析并操作body.raw
先将raw字段的JSON字符串解析为JSON对象,完成修改后再转回字符串(若需保留原字段格式),示例如下:
.. | objects | select(has("body") and .body.raw | type == "string") |= .body.raw = (.body.raw | fromjson | # 此处可添加任意对解析后JSON的操作,比如修改accountId、金额等 .accountId = "{{accountId}}" | .monetaryAmount.amount = 222 | tojson)
完整优化后的JQ代码
结合所有需求,同时处理key-value替换、body.raw解析修改及删除auth字段:
# 删除顶层auth字段 del(.auth) # 批量替换所有符合条件的key-value对象 | (.. | objects | select(has("key") and has("value"))) |= .value = "{{\(.key)}}" # 解析并修改body.raw内容 | (.. | objects | select(has("body") and .body.raw | type == "string")) |= .body.raw = (.body.raw | fromjson | .accountId = "{{accountId}}" | .monetaryAmount.amount = 222 | tojson)
代码说明
del(.auth):直接删除顶层auth字段,比递归查找更高效;(.. | objects | select(has("key") and has("value"))) |= ...:递归遍历所有符合条件的对象,批量替换value,避免冗余的逐个key匹配;.body.raw | fromjson:将字符串形式的JSON解析为JQ可操作的对象,修改完成后用tojson转回字符串,保留原始字段格式。
内容的提问来源于stack exchange,提问作者Tamás Horváth
相关产品推荐
相关产品推荐

