Katja Eichelberger
Katja Eichelberger

Reputation: 209

JQ: Delete key:value pairs anywhere in JSON tree

I am looking for a way to delete key:value pairs (where key is a known string) anywhere in the JSON tree with jq.

Specifically: I would like to delete "type": "Link" and "linkType": "Entry" everywhere (in all parts of the hierarchy, where ever they appear). My JSON file is +800000 rows long and is nested deeply.

Snippet:

{
  "entries": [
    {
      "sys": {
        "id": "vcLKKhJ3mZNfGMvVZZi07",
        "contentType": {
          "sys": {
            "id": "page"
          }
        }
      },
      "fields": {
        "title": {
          "de-DE": "Startseite",
          "en-US": "Home"
        },
        "description": {
          "en-US": "foo"
        },
        "keywords": {
          "en-US": "bar"
        },
        "stageModules": {
          "en-US": [
            {
              "sys": {
                "type": "Link",
                "linkType": "Entry",
                "id": "11AfBBuNK8bx3EygAS3WTY"
              }
            }
          ]
        }
      }
    }
  ]
}

I've tried so many different things to iterate through the file to remove these two from the output, I constantly end up with "Cannot index array with string". E.g.

[ .[] | select(.linkType != "Entry", .type != "Link" ) ]

Ideal result:

{
  "entries": [
    {
      "sys": {
        "id": "vcLKKhJ3mZNfGMvVZZi07",
        "contentType": {
          "sys": {
            "id": "page"
          }
        }
      },
      "fields": {
        "title": {
          "de-DE": "Startseite",
          "en-US": "Home"
        },
        "description": {
          "en-US": "foo"
        },
        "keywords": {
          "en-US": "bar"
        },
        "stageModules": {
          "en-US": [
            {
              "sys": {
                "id": "11AfBBuNK8bx3EygAS3WTY"
              }
            }
          ]
        }
      }
    }
  ]
}

Can someone help me out? Thank you for your help.

Upvotes: 1

Views: 1657

Answers (1)

pmf
pmf

Reputation: 36296

From the jq manual:

The walk(f) function applies f recursively to every component of the input entity.

Use this to recursively go through all items, check your conditions and use del if necessary:

walk(
  if type == "object" and .type == "Link" then del(.type) else . end
)

Edit: If "matching is less important", as you state, then just use del on any object:

walk(if type == "object" then del(.type, .linkType) else . end)

Upvotes: 3

Related Questions