如何使用JQ递归将JSON值替换为带$前缀的路径?
递归替换JSON值为带$前缀的键路径(含数组索引)
需求说明
需要递归处理复杂JSON对象,将每个键对应的字符串值替换为$开头的完整键路径(数组元素需包含索引)。
示例输入
{ "parent": { "name": "value", "child": { "child_value1": "value", "child_value2": "value", "child_value3": ["value1","value2"], "child_value4": { "child_child_value1":"value" } } } }
期望输出
{ "parent": { "name": "$name", "child": { "child_value1": "$child_child_value1", "child_value2": "$child_child_value2", "child_value3": ["$child_child_value3_0","$child_child_value3_1"], "child_value4": { "child_child_value1":"$child_child_value4_child_child_value1" } } } }
实际场景补充
使用如下配置文件:
{ "apis": { "order": { "base_url": "$mapping_base_url" }, "payment": { "base_url": "$admin_base_url" } }, "features": { "authentication": { "authProviders": true, "registration": false } }, "availableLocales":["en","es"] }
解决方案
可以借助JQ工具实现递归替换,核心命令如下:
jq '. |= reduce paths(strings) as $p (.; setpath($p; "$" + ($p | join("_"))))' input.json
执行结果
运行上述命令后得到的输出:
{ "apis": { "order": { "base_url": "$apis_order_base_url" }, "payment": { "base_url": "$apis_payment_base_url" } }, "features": { "authentication": { "authProviders": true, "registration": false } }, "availableLocales": [ "$availableLocales_0", "$availableLocales_1" ] }
命令说明
paths(strings):递归遍历JSON中所有值为字符串类型的节点路径,数组元素会自动带上索引(如availableLocales[0]对应路径["availableLocales", 0])reduce ... as $p (.; ...):逐个遍历每个目标路径$p,对原JSON对象进行迭代更新setpath($p; "$" + ($p | join("_"))):将路径$p对应位置的值,替换为$前缀加上路径各部分用下划线拼接的字符串
注意点
- 仅替换字符串类型的值,布尔、数字等非字符串类型的值会保持原样(如示例中
features下的布尔值未被修改) - 数组中的字符串元素会被处理,非字符串元素则不受影响
内容的提问来源于stack exchange,提问作者Vinicius Andrade
相关产品推荐
相关产品推荐

