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

使用jq将未知JSON标准化为指定Schema的技术求助

解决JSON格式统一的问题

需求回顾

你有两类JSON文件,需要将它们转换为统一结构:提取title、所有id值组成的列表、所有name值组成的列表。

两类输入格式分别为:

格式1

{
    "title": "Some data",
    "data": [
        {
            "id": "123",
            ...
        },
        {
            "id": "abc",
            ...
        }
    ]
}

格式2

{
  "title": "Some more data",
  "data": [
    {
      "ids": [
        {
          "id": "123",
          ...
        },
        {
          "id": "abc",
          ...
        }
      ],
      "names": [
        {
          "name": "A",
          ...
        },
        {
          "name": "B",
          ...
        }
      ]
    }
  ]
}

目标输出

{
  "title": "Some more data",
  "ids": [
      "123",
      "abc"
  ],
  "names": [
      "A",
      "B"
  ]
}

现有脚本问题

你当前的jq脚本会生成重复title的对象,原因是错误地遍历了所有嵌套对象,导致每个id/name都生成一个独立对象。

正确实现脚本

下面的脚本可以精准处理两类格式,输出统一结构:

for f in $(find . -type f -name "*.json" | sort); do
  jq 'map({
    title: .title,
    ids: (
      if .data[0] | has("id") then
        .data[].id
      elif .data[0] | has("ids") then
        .data[0].ids[].id
      else
        []
      end
    ),
    names: (
      if .data[0] | has("names") then
        .data[0].names[].name
      else
        []
      end
    )
  })' "$f" > "${f}.tmp" && mv "${f}.tmp" "$f"
done

脚本说明

  • map(...):遍历输入的JSON数组,对每个顶层对象单独处理
  • title:直接提取原对象的title字段
  • ids列表:
    • 先检查第一个data元素是否包含id字段,若是则提取所有data对象的id
    • 若第一个data元素包含ids数组,则遍历该数组提取每个子项的id
    • 无匹配时返回空数组
  • names列表:
    • 检查第一个data元素是否包含names数组,若是则提取所有子项的name
    • 无匹配时返回空数组
  • 使用临时文件${f}.tmp先保存结果,再替换原文件,避免直接写入导致的数据损坏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 14:05:29