Search code examples
jsonjqtext-manipulation

Using JQ to filter JSON data at different levels


I have this JSON data : some-json-file which contains the following

{
  "result": [
    {
      "id": "1234567812345678",
      "name": "somewebsite.com",
      "status": "active",
      "type": "secondary",
      "activated_on": "2021-12-12T15:44:40.444433Z",
      "plan": {
        "id": "77777777777777777777777777",
        "name": "Enterprise Website",
        "is_subscribed": true,
        "legacy_id": "enterprise",
        "externally_managed": true
      }
    }
  ],
  "result_info": {
    "page": 1,
    "total_pages": 1
  },
  "success": true,
  "messages": []
}

And I am trying to get this filtered output from it using jq

{
  "name": "somewebsite.com",
  "type": "secondary",
  "plan": {
    "name": "Enterprise Website",
    "id": "77777777777777777777777777"
  }
}

But I can't figure out how to do that.

I can filter the first layer of labels like this

cat some-json-file | jq '.result[] | {name,type,plan}'

Which gets me this output

{
  "name": "somewebsite.com",
  "type": "secondary",
  "plan": {
    "id": "77777777777777777777777777",
    "name": "Enterprise Website",
    "is_subscribed": true,
    "legacy_id": "enterprise",
    "externally_managed": true
  }
}

That gets me close, but I can't further filter the child labels under .plan so that I see just the .name and .id.

Any ideas? Thanks!


Solution

  • You were almost there. Just set the new context and use the same technique again:

    jq '.result[] | {name,type,plan: .plan | {name,id}}' some-json-file
    
    {
      "name": "somewebsite.com",
      "type": "secondary",
      "plan": {
        "name": "Enterprise Website",
        "id": "77777777777777777777777777"
      }
    }
    

    Demo

    Note: You don't need to cat the input, jq accepts the filename as parameter.