如何使用 jq 删除嵌套的键值对,其值具有具有特定值的更深的嵌套数组

How can I remove a nested key-value pair, whose value has a deeper nested array with a specific value by using jq

我目前正在尝试使用 jq 从 swagger json 文档中过滤掉一些路径值。

JSON 看起来像这样:

{
  "swagger": "2.0",
  "info": {
    "version": "1.0.2",
    "title": "Some API"
  },
  "host": "example.com",
  "basePath": "/",
  "paths": {
    "/api/companies": {
      "get": {
        "tags": [ "company-tag" ],
        "responses": {
          "200": {
            "description": "OK",
            "schema": { "$ref": "#/definitions/CompanyDTO" }
          }
        }
      }
    },
    "/api/account": {
      "get": {
        "tags": [ "account-tag" ],
        "operationId": "getAccount",
        "responses": {
          "200": {
            "description": "OK",
            "schema": { "$ref": "#/definitions/UserDTO" }
          }
        }
      },
      "post": {
        "tags": [ "account-tag" ],
        "operationId": "createAccount",
        "responses": {
          "200": {
            "description": "OK",
            "schema": { "$ref": "#/definitions/UserDTO" }
          }
        }
      }
    }
  }
}

我想过滤 paths 值,这样我就只能得到在 tags 中包含特定标签的路径数组。

例如:如果我想获取 account-tag 的路径,过滤后 JSON 应该如下所示:

{
  "swagger": "2.0",
  "info": {
    "version": "1.0.2",
    "title": "Some API"
  },
  "host": "example.com",
  "basePath": "/",
  "paths": {
    "/api/account": {
      "get": {
        "tags": [ "account-tag" ],
        "operationId": "getAccount",
        "responses": {
          "200": {
            "description": "OK",
            "schema": { "$ref": "#/definitions/UserDTO" }
          }
        }
      },
      "post": {
        "tags": [ "account-tag" ],
        "operationId": "createAccount",
        "responses": {
          "200": {
            "description": "OK",
            "schema": { "$ref": "#/definitions/UserDTO" }
          }
        }
      }
    }
  }
}

编辑

Ikegami 的第二个建议按预期工作。 这是我的最终 solution

如果我们假设给定路径的所有方法(getpost 等)共享相同的标签,我们可以简单地使用以下内容:

.paths |= with_entries( select( .value[].tags | index("account-tag") ) )

Demo 在 jqplay


如果该假设不成立,我们将需要在两个级别进行过滤。

.paths |= with_entries(
   .value |= with_entries(
      select( .value.tags | index("account-tag") )
   ) |
   select( .value | length > 0 )
)

Demo 在 jqplay

.paths |= with_entries(
   .value = (
      .value |
      with_entries(
         select( .value.tags | index("account-tag") )
      ) |
      select( length > 0 )
   )
)

Demo 在 jqplay

(我讨厌在这里必须使用 .value = ( .value | ... ) 而不是 .value |= ( ... )。)