使用 jq 使用属性之一对 json 中的键进行排序

Use jq to sort keys in json using one of the properties

我需要按自然顺序键对以下 JSON 文件进行排序,但“必需”部分中列出的键应该排在第一位,该怎么做?

以下命令仅通过键将它们按自然顺序排序:

jq --sort-keys . /tmp/source.json > ./tmp/target.json
{
   "Request": {
        "properties": {
          "capacity": {
            "$ref": "SubscriptionCapacity"
          },
          "metadata": {
            "$ref": "MeterDefinitionsAndPolicy"
          },
          "data": {
            "type": "string"
          },
          "avs": {
            "pattern": "standard:v2",
            "type": "string"
          }
        },
        "required": [
          "data",
          "avs"
        ],
        "type": "object"
      }
}

预期输出应如下所示:

{
   "Request": {
        "properties": {
          "avs": {
            "$ref": "Pricing"
          },
          "data": {
            "type": "string"
          }
          "capacity": {
            "$ref": "SubscriptionCapacity"
          },
          "metadata": {
            "$ref": "MeterDefinitionsAndPolicy"
          }
        },
        "required": [
          "data",
          "avs"
        ],
        "type": "object"
      }
}

可以按照

做一些事情
.Request.required as $req
| .Request.properties |= (
    to_entries
    | sort_by(.key)
    | group_by(IN(.key; $req[]) | not)
    | map(from_entries)
    | add
  )
{
  "Request": {
    "properties": {
      "avs": {
        "pattern": "standard:v2",
        "type": "string"
      },
      "data": {
        "type": "string"
      },
      "capacity": {
        "$ref": "SubscriptionCapacity"
      },
      "metadata": {
        "$ref": "MeterDefinitionsAndPolicy"
      }
    },
    "required": [
      "data",
      "avs"
    ],
    "type": "object"
  }
}

Demo

但您不能保证在任何后续处理之后顺序将保持与通常对象相同没有顺序,数组有。

这是一种直接且相当有效的方法,它利用了 keys 将键名称生成为排序数组的事实:

. as $in
| .Request
| (.required|sort) as $required
| (.properties|keys) as $all
| ($all - $required) as $optional
| .properties as $p
| $in
| .Request.properties = reduce ($required[], $optional[]) as $key ({}; . + {($key): $p[$key]} )


请注意,gojq(jq 的 Go 实现)确实支持 keys,但通常不遵循用户指定的对象内键的顺序。