skip to Main Content

How can I get the first x levels of depth of an object and remove the rest using jq ?

I have the following example:

{
  "Service1": {
    "Production": {
      "Location 1": {
        "b2d1": {
          "clusters": {
            "Datacenter2": []
          },
          "prod": {
            "clusters": {
              "Datacenter1": []
            }
          }
        }
      },
      "Service2": {
        "Production": {
          "Location 1": {
            "dr1": {
              "clusters": {
                "Datacenter3": []
              },
              "prod": {
                "clusters": {
                  "Datacenter1": []
                }
              }
            }
          }
        }
      }
    }
  }
}

In my case, I want to get the 1st 3 levels (want to remove everything bellow location in all entries.

3

Answers


  1. You could get all the paths of length > 3 (actually == 4 would suffice), and delete those using delpaths:

    jq 'delpaths([paths | select(length > 3)])' file.json
    
    {
      "Service1": {
        "Production": {
          "Location 1": {},
          "Service2": {}
        }
      }
    }
    

    Demo

    Note that Service2 is already on third level, so it is cut off immediately (without going down to its own Location 1 field).

    Login or Signup to reply.
  2. Here is one way:

    $ jq 'del(.[][][][])' file
    {
      "Service1": {
        "Production": {
          "Location 1": {},
          "Service2": {}
        }
      }
    }
    $
    
    Login or Signup to reply.
  3. From the question and example, it’s not too clear how arrays should be handled, so the following may be of interest as it makes a clear distinction between JSON objects and all else:

    # If the input is an object then:
    #   if depth <= 0 then emit {}, otherwise map_values(retain(depth - 1));
    #   otherwise echo the input.
    def retain(depth):
      if type == "object"
      then if depth <= 0 then {}
           else map_values(retain(depth - 1))
           end
      else .
      end;
    
    retain(3)
    

    For the sample input, the output would be:

    {
      "Service1": {
        "Production": {
          "Location 1": {},
          "Service2": {}
        }
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search