You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用jq条件修改JSON内容并保留原结构?附常见问题解析

使用jq修改JSON数组对象的优化方案与常见问题解析

一、更简洁的jq写法

假设你的input.json结构如下:

{
  "signal": [
    {"name": "signal1", "nested": {"prop": "old_value"}},
    {"name": "temperature", "nested": {"prop": "unchanged"}},
    {"name": "signal5", "nested": {"prop": "old_value"}}
  ],
  "metadata": "保留原有内容"
}

可以用这条更简洁的命令完成需求:

jq '.signal |= map(select(.name | contains("signal")) |= (.nested.prop = "CHANGED-" + (.name | match("\\d$").string)) // .)' input.json

写法说明:

  • .signal |= map(...):直接定位到signal数组,用map遍历并修改数组元素,修改后重新赋值回原字段,保证整体结构不变。
  • select(.name | contains("signal")):精准筛选出name包含"signal"的对象。
  • (.nested.prop = "CHANGED-" + (.name | match("\\d$").string)):提取name最后一位数字,拼接成目标字符串后赋值给.nested.prop。
  • // .:确保不匹配筛选条件的对象原样保留,避免被过滤掉。

二、为什么之前的写法会输出多个JSON对象?

出现这种情况通常是以下两种原因:

  • 直接遍历数组元素而非修改原数组:如果你的写法是类似jq '.signal[] | select(.name | contains("signal")) | .nested.prop = ...',这种写法会直接遍历signal数组的每个元素,对匹配的元素单独修改后输出,而不会把修改后的元素放回原数组、保留外层结构。最终每个被修改的元素都会被输出成一个独立的JSON对象。
  • 未使用|=绑定修改到原对象:如果没有用|=把修改操作绑定到原数组或原对象上,而是直接输出修改后的片段,jq会把每个处理结果单独输出,导致多个JSON对象。

举个反例(会输出多个JSON):

# 错误写法,不要用这个
jq '.signal[] | select(.name | contains("signal")) | .nested.prop = "CHANGED-" + (.name | match("\\d$").string)' input.json

这个命令会输出两个独立的JSON对象(对应示例里的signal1和signal5),而不是完整的原JSON结构。

内容的提问来源于stack exchange,提问作者Daniel Kaplan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 02:00:00