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

使用jq合并两个JSON文件并对相同路径整数求和

用JQ合并两个JSON文件并对同路径整数值求和

我有两个结构相似的JSON文件,其中以x开头的键名称可变且数量不定,其他键(如views、all)固定。大部分x开头的键在两个文件中都存在,但部分仅存在于其中一个文件。我需要合并这两个文件,并对相同路径的整数值进行求和,仅在单个文件中存在的键则保留原值。

示例输入文件

文件1:

{
    "xFruits": {
        "views": 163,
        "all": {
            "xApples": {
                "views": 28,
                "eats": 10,
                "discards": 17
            }
        }
    },
    "xVegetables": {
        "views": 134,
        "all": {
            "xBeans": {
                "views": 29,
                "eats": 11,
                "discards": 14
            },
            "xCarrots": {
                "views": 30,
                "eats": 12,
                "discards": 11
            }
        }
    }
}

文件2:

{
    "xFruits": {
        "views": 16,
        "all": {
            "xApples": {
                "views": 2,
                "eats": 2,
                "discards": 5
            }
        }
    },
    "xVegetables": {
        "views": 147,
        "all": {
            "xBeans": {
                "views": 12,
                "eats": 7,
                "discards": 13
            },
            "xSpinach": {
                "views": 30,
                "eats": 12,
                "discards": 11
            }
        }
    }
}

期望合并结果

{
    "xFruits": {
        "views": 179,
        "all": {
            "xApples": {
                "views": 30,
                "eats": 12,
                "discards": 22
            }
        }
    },
    "xVegetables": {
        "views": 281,
        "all": {
            "xBeans": {
                "views": 41,
                "eats": 18,
                "discards": 27
            },
            "xCarrots": {
                "views": 30,
                "eats": 12,
                "discards": 11
            },
            "xSpinach": {
                "views": 30,
                "eats": 12,
                "discards": 11
            }
        }
    }
}

解决方案:用JQ实现

完全可以用JQ实现这个需求,核心思路是递归合并两个JSON对象,遇到数值类型时求和,遇到对象类型时继续递归合并,键不存在时直接保留现有值。

简化递归版命令

假设两个文件分别名为file1.json和file2.json,运行以下命令:

jq -s '
def merge_sum($a; $b):
    ($a | type) as $atype
    | ($b | type) as $btype
    | if $atype == "object" and $btype == "object" then
        ($a + $b) | reduce keys[] as $k (.;
            .[$k] = merge_sum($a[$k]; $b[$k])
        )
    elif $atype == "number" and $btype == "number" then
        $a + $b
    else
        $b // $a
    end;

reduce .[] as $item ({}; merge_sum(.; $item))
' file1.json file2.json

逻辑解释

  1. -s:将输入的多个JSON文件读入一个数组中
  2. 自定义递归函数merge_sum:
    • 若两个值都是对象:合并键集合后,对每个键递归执行合并逻辑
    • 若两个值都是数值:直接求和
    • 其他情况:保留存在的那个值(优先取第二个文件的值,若不存在则取第一个)
  3. 外层reduce:遍历数组中的每个文件对象,逐步合并到初始空对象中

这个版本能自动处理任意深度的JSON结构,扩展性更强,逻辑也更清晰。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:25:18