jq:选择和删除嵌套字段

jq: pick and remove nested fields

这是我的 json:

[
  {
    "id": "7250078e-5fbf-43d7-9c67-94b88fbf44d8",
    "priority": 0,
    "httpRequest": {
      "method": "POST",
      "path": "/catalog-data-rest/oid/search.xml",
      "headers": {
        "Host": [
          "preproduccio.gcatalegs.isisscat.intranet.gencat.cat:8443"
        ],
        "Authorization": [
          "Basic VVNVTVBJVFNUOkJ4c2w3MjU5"
        ],
        "User-Agent": [
          "curl/7.58.0"
        ],
        "Accept": [
          "*/*"
        ],
        "Content-Type": [
          "text/html; charset=utf-8"
        ],
        "Content-Length": [
          "94"
        ]
      },
      "keepAlive": true,
      "secure": true,
      "body": {
        "type": "STRING",
        "string": "<request><oid>2.16.724.4.402</oid><startIndex>1</startIndex><pageSize>100</pageSize></request>",
        "rawBytes": "PHJlcXVlc3Q+PG9pZD4yLjE2LjcyNC40LjQwMjwvb2lkPjxzdGFydEluZGV4PjE8L3N0YXJ0SW5kZXg+PHBhZ2VTaXplPjEwMDwvcGFnZVNpemU+PC9yZXF1ZXN0Pg==",
        "contentType": "text/html; charset=utf-8"
      }
    },
    "httpResponse": {
      "statusCode": 200,
      "reasonPhrase": "OK",
      "headers": {
        "Date": [
          "Tue, 20 Jul 2021 11:07:40 GMT"
        ],
        "X-Powered-By": [
          "Servlet/3.0"
        ],
        "X-Content-Type-Options": [
          "nosniff"
        ],
        "X-XSS-Protection": [
          "1; mode=block"
        ],
        "Cache-Control": [
          "no-cache, no-store, max-age=0, must-revalidate"
        ],
        "Pragma": [
          "no-cache"
        ],
        "Expires": [
          "0"
        ],
        "Strict-Transport-Security": [
          "max-age=31536000 ; includeSubDomains"
        ],
        "X-Frame-Options": [
          "DENY"
        ],
        "Set-Cookie": [
          "JSESSIONID=0000r6GgpYaB7bQiXRaS8zB8qw8:19pp48tgo; Path=/; HttpOnly"
        ],
        "Keep-Alive": [
          "timeout=10, max=100"
        ],
        "Connection": [
          "Keep-Alive"
        ],
        "Content-Type": [
          "application/xml"
        ],
        "Content-Language": [
          "en-US"
        ],
        "content-length": [
          "29089"
        ]
      },
      "cookies": {
        "JSESSIONID": "0000r6GgpYaB7bQiXRaS8zB8qw8:19pp48tgo"
      },
      "body": {
        "type": "XML",
        "xml": "string-value",
        "rawBytes": "string-value",
        "contentType": "application/xml"
      }
    },
    "times": {
      "remainingTimes": 1
    },
    "timeToLive": {
      "unlimited": true
    }
  }
]

我需要删除并选择以下字段:

我需要从 .httpRequest 中删除:

.httpRequest.headers
.httpRequest.keepAlive
.httpRequest.secure
.httpRequest.body.rawBytes

想要的结果:

    "httpRequest": {
      "method": "POST",
      "path": "/catalog-data-rest/oid/search.xml",
      "body": {
        "type": "STRING",
        "string": "<request><oid>2.16.724.4.402</oid><startIndex>1</startIndex><pageSize>100</pageSize></request>",
        "contentType": "text/html; charset=utf-8"
      }
    }

我需要从 .httpResponse 中选择:

.httpResponse.statusCode
.httpResponse.reasonPhrase
.httpResponse.headers.Content-Type
.httpResponse.headers.content-lenght

我需要从 .httpResponse 中删除:

.httpResponse.body.rawBytes

期望的结果是:

    "httpResponse": {
      "statusCode": 200,
      "reasonPhrase": "OK",
      "headers": {
        "Content-Type": [
          "application/xml"
        ],
        "content-length": [
          "29089"
        ]
      },
      "body": {
        "type": "XML",
        "xml": "string-value",
        "contentType": "application/xml"
      }
    }

所以我的最终 json 将是:

[
  {
    "httpRequest": {
      "method": "POST",
      "path": "/catalog-data-rest/oid/search.xml",
      "body": {
        "type": "STRING",
        "string": "<request><oid>2.16.724.4.402</oid><startIndex>1</startIndex><pageSize>100</pageSize></request>",
        "contentType": "text/html; charset=utf-8"
      }
    },
    "httpResponse": {
      "statusCode": 200,
      "reasonPhrase": "OK",
      "headers": {
        "Content-Type": [
          "application/xml"
        ],
        "content-length": [
          "29089"
        ]
      },
      "body": {
        "type": "XML",
        "xml": "string-value",
        "contentType": "application/xml"
      }
    }
  }
]

我希望我解释得很好。

到目前为止我已经可以得到this demo

这是您可以做到的一种方法:

parse.jq

# We are only interested in the request and response objects
.[] | [ { httpRequest, httpResponse } ] |

# Delete unwanted paths
del(
    .[].httpRequest.headers,
    .[].httpRequest.keepAlive,
    .[].httpRequest.secure,
    .[].httpRequest.body.rawBytes,
    .[].httpResponse.body.rawBytes
) |

# Reshape the httpResponse object
.[].httpResponse |= 
  ( 
    {
      statusCode,
      reasonPhrase,
      "headers" : {
        "Content-Type"   : .headers."Content-Type",
        "content-length" : .headers."content-length"
      },
      body 
    }
  )

运行 像这样:

jq -f parse.jq infile.json

输出:

[
  {
    "httpRequest": {
      "method": "POST",
      "path": "/catalog-data-rest/oid/search.xml",
      "body": {
        "type": "STRING",
        "string": "<request><oid>2.16.724.4.402</oid><startIndex>1</startIndex><pageSize>100</pageSize></request>",
        "contentType": "text/html; charset=utf-8"
      }
    },
    "httpResponse": {
      "statusCode": 200,
      "reasonPhrase": "OK",
      "headers": {
        "Content-Type": [
          "application/xml"
        ],
        "content-length": [
          "29089"
        ]
      },
      "body": {
        "type": "XML",
        "xml": "string-value",
        "contentType": "application/xml"
      }
    }
  }
]

选择时新建object(使用{}),删除时使用del

map({
   "httpRequest": (
      .httpRequest |
      del(.headers, .keepAlive, .secure, .body.rawBytes)
   ),
   "httpResponse": (
      .httpResponse |
      del(.body.rawBytes) |
      {
         statusCode,
         reasonPhrase,
         "headers": {
            "Content-Type":   .headers."Content-Type",
            "Content-Length": .headers."content-length"
         },
         body
      }
   )
})

jqplay

这个解决方案和 previously-posted 解决方案的问题是 HTTP headers 是 case-insensitive,所以我不认为 .headers."Content-Type".headers."content-length" 将永远有效。根据需要进行调整。