skip to Main Content

I would like to create a json object starting with a list of string in json format as the following

[
  "nonprod/global/app/sit01",
  "nonprod/global/app/dev02",
  "prod/na/app/prod01",
  "test/eu/app/cust01",
  "nonprod/global/app/dev03"
]

What I would like to obtain is a map of lists of strings which would have as key the first two words of the string from the list and as value the strings that starts with that specific key.

I’ve tried the following:

jq 'reduce (.[] | capture("(?<env_type>([^/]*/[^/]*))").env_type as $key | {($key) : [.]}) as $item ({}; . *= $item)'

And obtained:

{
  "nonprod/global": [
    "nonprod/global/app/dev03"
  ],
  "prod/na": [
    "prod/na/app/prod01"
  ],
  "test/eu": [
    "test/eu/app/cust01"
  ],
  "prod/eu": [
    "prod/eu/app/prod01"
  ]
}

I’m expecting:

{
  "nonprod/global":[
    "nonprod/global/app/sit01",
    "nonprod/global/app/dev02",
    "nonprod/global/app/dev03"
  ],
  "prod/eu":[
    "prod/eu/app/prod01"
  ],
  
  "prod/na":[
    "prod/na/app/prod01"
  ],
  "test/eu":[
    "test/eu/app/cust01"
  ]
}

2

Answers


  1. which would have as key the first two words

    You can define a function that splits at the second slash, then usi it to group_by the input array, creating an array of arrays, then use INDEX to turn it into an object, using the same function on the first item.

    def f: .[:indices("/")[1]];
    group_by(f) | INDEX(first | f)
    
    {
      "nonprod/global": [
        "nonprod/global/app/sit01",
        "nonprod/global/app/dev02",
        "nonprod/global/app/dev03"
      ],
      "prod/na": [
        "prod/na/app/prod01"
      ],
      "test/eu": [
        "test/eu/app/cust01"
      ]
    }
    

    Demo

    Login or Signup to reply.
  2. Use += to add to an array. If the key doesn’t exist, jq will create it on the fly (null + [] evaluates to []):

    reduce (.[] | capture("^(?<env>(?<type>[^/]*/[^/]*).*)$")) as {$env, $type} 
    ({}; .[$type] += [$env])
    
    {
      "nonprod/global": [
        "nonprod/global/app/sit01",
        "nonprod/global/app/dev02",
        "nonprod/global/app/dev03"
      ],
      "prod/na": [
        "prod/na/app/prod01"
      ],
      "test/eu": [
        "test/eu/app/cust01"
      ]
    }
    

    Demo

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search