我有1000多个代表游戏元素的JSON文件.这是一个典型的例子:

{
    "name": "Reeve Hunter",
    "edition": 3,
    "revision": "2021 v1",
    "keywords": [
        "Circle",
        "Wolf Sworn",
        "Reeve of Orboros",
        "Solo"
    ],
    "point cost": 4,
    "field allowance": 2,
    "models": [
        {
            "Hunter": {
                "spd": 6,
                "str": 6,
                "mat": 6,
                "rat": 7,
                "def": 13,
                "arm": 13,
                "cmd": 7,
                "boxes": 5,
                "advantages": [
                    "Advance Deploy",
                    "Assault",
                    "Pathfinder"
                ],
                "base size": 30,
                "attacks": [
                    {
                        "Double Crossbow": {
                            "type": "ranged",
                            "rng": 12,
                            "rof": 2,
                            "pow": 10
                        }
                    },
                    {
                        "Battle Blade": {
                            "type": "melee",
                            "rng": 0.5,
                            "pow": 3,
                            "p+s": 9
                        }
                    },
                    {
                        "Cleft Sword": {
                            "type": "melee",
                            "rng": 1,
                            "pow": 5,
                            "p+s": 11,
                            "weapon qualities": ["Weapon Master"],
                            "abilities": ["Powerful Charge"]
                        }
                    }
                ],
                "abilities": [
                    "Hunter",
                    "Leadership [Reeves of Orboros]",
                    "Quickwork",
                    "Sprint"
                ]
            }
        }
    ]
}

虽然上面的JSON是有效的,但一旦我将所有JSON文件放入MongoDB数据库中,我就意识到我无法正确分析我的数据,因为modelsattacks数组中的每个子文档都有一个唯一的名称作为键.

我想像这样转换每个JSON文档:

{
  "name": "Reeve Hunter",
  "edition": 3,
  "revision": "2021 v1",
  "keywords": [
    "Circle",
    "Wolf Sworn",
    "Reeve of Orboros",
    "Solo"
  ],
  "point cost": 4,
  "field allowance": 2,
  "models": [
    {
      "model name": "Hunter",
      "spd": 6,
      "str": 6,
      "mat": 6,
      "rat": 7,
      "def": 13,
      "arm": 13,
      "cmd": 7,
      "boxes": 5,
      "advantages": [
        "Advance Deploy",
        "Assault",
        "Pathfinder"
      ],
      "base size": 30,
      "attacks": [
        {
          "attack name": "Double Crossbow",
          "type": "ranged",
          "rng": 12,
          "rof": 2,
          "pow": 10
        },
        {
          "attack name": "Battle Blade",
          "type": "melee",
          "rng": 0.5,
          "pow": 3,
          "p+s": 9
        },
        {
          "attack name": "Cleft Sword",
          "type": "melee",
          "rng": 1,
          "pow": 5,
          "p+s": 11,
          "weapon qualities": [
            "Weapon Master"
          ],
          "abilities": [
            "Powerful Charge"
          ]
        }
      ],
      "abilities": [
        "Hunter",
        "Leadership [Reeves of Orboros]",
        "Quickwork",
        "Sprint"
      ]
    }
  ]
}

我很擅长使用awksed来清理文本,但是这个转换很复杂,而且有足够多的"问题",我觉得我需要一个不同的策略.

我一直在使用出色的工具jq操作和查询JSON文件,我觉得必须有一种方法来利用它的能力来做我需要的事情.

有没有人对编写脚本的最佳策略有什么建议,该脚本可以将我所有的数据转换为我需要的更干净的格式?

推荐答案

您可以使用to_entries将嵌套对象分解为.key.value,然后使用|=重新排列和更新:

<file.json jq '.models |= map(to_entries[] | {"model name": .key} + .value)
  | .models[].attacks |= map(to_entries[] | {"attack name": .key} + .value)'
{
  "name": "Reeve Hunter",
  "edition": 3,
  "revision": "2021 v1",
  "keywords": [
    "Circle",
    "Wolf Sworn",
    "Reeve of Orboros",
    "Solo"
  ],
  "point cost": 4,
  "field allowance": 2,
  "models": [
    {
      "model name": "Hunter",
      "spd": 6,
      "str": 6,
      "mat": 6,
      "rat": 7,
      "def": 13,
      "arm": 13,
      "cmd": 7,
      "boxes": 5,
      "advantages": [
        "Advance Deploy",
        "Assault",
        "Pathfinder"
      ],
      "base size": 30,
      "attacks": [
        {
          "attack name": "Double Crossbow",
          "type": "ranged",
          "rng": 12,
          "rof": 2,
          "pow": 10
        },
        {
          "attack name": "Battle Blade",
          "type": "melee",
          "rng": 0.5,
          "pow": 3,
          "p+s": 9
        },
        {
          "attack name": "Cleft Sword",
          "type": "melee",
          "rng": 1,
          "pow": 5,
          "p+s": 11,
          "weapon qualities": [
            "Weapon Master"
          ],
          "abilities": [
            "Powerful Charge"
          ]
        }
      ],
      "abilities": [
        "Hunter",
        "Leadership [Reeves of Orboros]",
        "Quickwork",
        "Sprint"
      ]
    }
  ]
}

Demo

Json相关问答推荐

从Json响应中为需要每个值的Post请求提取多个值

如何在Haskell中解析JSON,其中字段的名称可以是多个值之一,但应该转换为单个Haskell类型?

对一些JSON模式验证的混淆

jq 对特定键进行过滤并将值整理到单个 csv 单元格中

将 std::可选值存储到 json 文件 C++

使用 Power BI 中的 Deneb 视觉效果绘制面积图中的 X 轴日期

基于JQ中另一个对象的值 Select 对象

APIM 生成 JsonArray 到 EventHub

将=分隔值文件转换为:json文件

如何使用 SQL Server 将 json 存储为字符串的列分解/规范化为行和列?

如何使用nifi从json文件中过滤属性

JOLT JSON 将值从一对多转换为一对一

jq:来自嵌套 JSON 的映射

通过一个序列化器更新多个模型数据

流导入错误:重新上传时不存在布局释放 UUID

如何使用 boost::json::value 调用无参数函数

Powershell JSON 操作

使用绝对或相对路径在 curl 请求中发送 json 文件

Microsoft.Net.Http 与 Microsoft.AspNet.WebApi.Client

XML vs YAML vs JSON