如何使用jq检测并报告JSON中任意层级的重复对象键?
使用jq检测并报告任意层级的重复JSON对象键
普通jq解析JSON时会自动覆盖重复的对象键,所以必须借助--stream参数捕获原始的结构流,才能检测到所有层级的重复键。以下是具体实现:
基础检测命令
针对你的示例JSON,执行下面的命令即可找出所有重复键及其路径:
jq --stream 'select(length == 2) | .[0]' input.json | jq -n '[inputs] | group_by(.)[] | select(length>1) | {path: ., count: length}'
命令拆解
第一步捕获所有键路径:
jq --stream 'select(length == 2) | .[0]' input.json--stream将JSON拆分为[路径数组, 值]的结构流select(length == 2)筛选出完整的键值项(排除中间结构节点).[]提取每个键对应的路径数组(比如顶层a的路径是["a"],深层x.y的路径是["x","y"])
第二步统计重复项:
jq -n '[inputs] | group_by(.)[] | select(length>1) | {path: ., count: length}'- 将第一步输出的所有路径数组收集成数组
group_by(.)按路径分组select(length>1)筛选出出现多次的路径- 最终输出包含重复路径和重复次数的对象
示例输出
针对你提供的JSON:
{ "a":{ "b": 1 }, "a":{ "c": 1 } }
运行命令后会输出:
{ "path": ["a"], "count": 2 }
优化路径格式(可选)
如果想把路径数组转为更易读的点分隔格式(比如.a或.x.y),可以修改命令为:
jq --stream 'select(length == 2) | .[0]' input.json | jq -n '[inputs] | group_by(.)[] | select(length>1) | {path: ("." + (. | join("."))), count: length}'
输出的path会变成".a",更贴近jq的路径语法。
深层重复检测示例
如果JSON存在深层重复键,比如:
{ "x": { "y": 1, "y": 2 }, "x": { "z": 3 } }
运行命令会同时检测出顶层x和深层x.y的重复:
{ "path": ["x"], "count": 2 } { "path": ["x", "y"], "count": 2 }
内容的提问来源于stack exchange,提问作者Shang Jian Ding
相关产品推荐
相关产品推荐

