使用jq过滤JSON外部对象,包括内部数组中只有一个最大对象

时间:2016-04-05 22:58:54

标签: json jq

我有一个稍微修改过的JSON文件,其中包含来自https://api.ipsw.me/v2.1/firmwares.json的iOS固件信息。这是一个简化版本:

输入

{
  "AppleTV5,3": {
    "firmwares": [
      {
        "version": "9.2",
        "buildid": "13Y234"
      },
      {
        "version": "9.1.1",
        "buildid": "13U717"
      },
      {
        "version": "9.1",
        "buildid": "13U85"
      }
    ],
    "bdid": 52,
    "name": "Apple TV 4 (2015)"
  },
  "AppleTV3,2": {
    "firmwares": [
      {
        "version": "8.4.1",
        "buildid": "12H523"
      },
      {
        "version": "8.3",
        "buildid": "12F69"
      }
    ],
    "bdid": 0,
    "name": "Apple TV 3 (2013)"
  },
  "AppleTV3,1": {
    "firmwares": [
      {
        "version": "8.4.1",
        "buildid": "12H523"
      },
      {
        "version": "8.3",
        "buildid": "12F69"
      },
      {
        "version": "8.2",
        "buildid": "12D508"
      }
    ],
    "bdid": 0,
    "name": "Apple TV 3"
  }
}

我想编写一个jq查询,它返回每个外部对象,只包含firmwares数组中的最新固件对象。 E.g:

所需的输出

{
  "AppleTV5,3": {
    "firmwares": [
      {
        "version": "9.2",
        "buildid": "13Y234"
      }
    ],
    "bdid": 52,
    "name": "Apple TV 4 (2015)"
  },
  "AppleTV3,2": {
    "firmwares": [
      {
        "version": "8.4.1",
        "buildid": "12H523"
      }
    ],
    "bdid": 0,
    "name": "Apple TV 3 (2013)"
  },
  "AppleTV3,1": {
    "firmwares": [
      {
        "version": "8.4.1",
        "buildid": "12H523"
      }
    ],
    "bdid": 0,
    "name": "Apple TV 3"
  }
}

我可以通过以下方式获取最新firmwares个对象的列表:

.[].firmwares | max_by(.version)

我只能从version获取值:

.[].firmwares | map(.version | values) | max

我可以通过firmwares与特定version匹配来获取外部AppleTV对象:

[ . | to_entries[] | .value.firmwares |= map ( select ( .version == "8.3" ) ) ] | from_entries

但我似乎无法将这些技术结合起来以获得我想要的输出。任何人都可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

您应该将其视为更新firmwares数组。我们正在使用已过滤的版本对其进行更新,并选择最高版本。

.[].firmwares |= [ max_by(.version | split(".") | map(tonumber)) // empty ]

答案 1 :(得分:1)

以下解决方案使用 reduce 访问对象的每个键并将相应的.firmwares更新为最新版本

reduce keys[] as $i (
    .
  ; .[$i].firmwares |= [max_by(.version)]
)