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

JQ工具库问题:如何用另一JSON对象递归覆盖现有键值且不新增属性

用JQ实现顶层保留目标结构、嵌套层级合并替换

从你的示例来看,需求是:

  • 顶层仅保留config_new.json的键,用config.json中对应键的值替换
  • 嵌套对象层级:合并config.json的键到config_new.json的嵌套对象中(允许嵌套层级添加config里的额外键)

原命令用*会把config的顶层额外键也带入,不符合要求,下面是精准实现的命令:

解决命令

jq -n '
(inputs | .) as $config_new | input as $config |
$config_new | with_entries(
  .value = (
    if .value | type == "object" and $config[.key] | type == "object" then
      .value + $config[.key]
    else
      $config[.key] // .value
    end
  )
)
' config_new.json config.json

命令说明

  1. 读取输入:先加载config_new作为目标结构,再加载config作为替换源
  2. 处理顶层键:用with_entries遍历config_new的所有顶层键,确保只保留这些键
  3. 值替换逻辑:
    • 如果当前键对应的值是对象,且config中该键的值也是对象,就合并两个对象(config的嵌套键会被加入)
    • 否则,优先用config中的值替换,没有的话保留config_new原有的值

验证结果

用你提供的文件执行命令后,输出和你期望的完全一致:

{
  "name": "testName",
  "age": "tooYoung",
  "properties": {
    "title": "Mr",
    "fruits": ["banana"],
    "height": "tooTall"
  }
}

如果你需要所有层级都严格只保留config_new的键(包括嵌套层级不添加额外键),可以用下面的递归命令:

jq -n '
def deep_merge_strict($source):
  . as $target |
  reduce keys[] as $key (
    {};
    if $target[$key] | type == "object" and $source[$key] | type == "object" then
      .[$key] = ($target[$key] | deep_merge_strict($source[$key]))
    elif $source | has($key) then
      .[$key] = $source[$key]
    else
      .[$key] = $target[$key]
    end
  );
(inputs | .) as $config_new | input as $config | $config_new | deep_merge_strict($config)
' config_new.json config.json

这个命令执行后,嵌套层级的height不会被保留,因为config_new的properties里没有这个键。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:10:40