Search code examples
jq

Deleting multiple keys at once with jq


I need to delete multiple keys at once from some JSON (using jq), and I'm trying to learn if there is a better way of doing this, than calling map and del every time. Here's my input data:

test.json

[
  {
    "label": "US : USA : English",
    "Country": "USA",
    "region": "US",
    "Language": "English",
    "locale": "en",
    "currency": "USD",
    "number": "USD"
  },
  {
    "label": "AU : Australia : English",
    "Country": "Australia",
    "region": "AU",
    "Language": "English",
    "locale": "en",
    "currency": "AUD",
    "number": "AUD"
  },
  {
    "label": "CA : Canada : English",
    "Country": "Canada",
    "region": "CA",
    "Language": "English",
    "locale": "en",
    "currency": "CAD",
    "number": "CAD"
  }
]

For each item, I want to remove the number, Language, and Country keys. I can do that with this command:

$ cat test.json | jq 'map(del(.Country)) | map(del(.number)) | map(del(.Language))'

That works fine, and I get the desired output:

[
  {
    "label": "US : USA : English",
    "region": "US",
    "locale": "en",
    "currency": "USD"
  },
  {
    "label": "AU : Australia : English",
    "region": "AU",
    "locale": "en",
    "currency": "AUD"
  },
  {
    "label": "CA : Canada : English",
    "region": "CA",
    "locale": "en",
    "currency": "CAD"
  }
]

However, I'm trying to understand if there is a jq way of specifying multiple labels to delete, so I don't have to have multiple map(del()) directives?


Solution

  • You can provide a stream of paths to delete:

    $ cat test.json | jq 'map(del(.Country, .number, .Language))'
    

    Also, consider that, instead of blacklisting specific keys, you might prefer to whitelist the ones you do want:

    $ cat test.json | jq 'map({label, region, locale, currency})'