Home > OS >  JQ: Delete key:value pairs anywhere in JSON tree
JQ: Delete key:value pairs anywhere in JSON tree

Time:09-30

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.

CodePudding user response:

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)
  • Related