MUHAHA
MUHAHA

Reputation: 1867

jq: recursion -> nested arrays

How can I parse this json structure with jq? It should loop over leafs (projects and groups) recursively.

My use case is: create project and groups in VCS with CLI. Group can have multiple projects, group can be empty, projects must have parent group created in advance.

Similar analogy would be:

Thanks

{
   "structure":[
      {
         "name":"rootgroup1",
         "type":"group",
         "nested":[
            {
               "name":"nestedproject1",
               "type":"project"
            },
            {
               "name":"nestedgroup1",
               "type":"group",
               "nested":[
                  {
                     "name":"nestednestedproject2",
                     "type":"project"
                  }
               ]
            }
         ]
      },
      {
         "name":"rootproject1",
         "type":"project"
      },
      {
         "name":"rootgroup2",
         "type":"group",
         "nested": []
      }
   ]
}

Expected output:

"rootgroup1","group",""
"nestedproject1","project","rootgroup1"
"nestedgroup1","group","rootgroup1"
"nestednestedproject2","group","rootgroup1/nestedgroup1"
"rootproject1","project",""
"rootgroup2","group",""

Try:

jq -r '.structure[] | .. | "\(.name?) \(.type?)"'

Still not sure, how create a parent path.

Upvotes: 2

Views: 477

Answers (1)

peak
peak

Reputation: 117067

The following implements a solution to the problem as I understand it:

# $prefix is an array interpreted as the prefix
def details($prefix):
  def out:
    select(has("name") and has("type")) | [.name, .type, "/" + ($prefix|join("/"))];

  out,
    if (.nested | (. and length>0))
    then .name as $n | .nested[] | details($prefix + [$n]) 
    else empty
    end;
  
.structure[]
| details([])
| @csv

Given your sample input, the output would be:

"rootgroup1","group","/"
"nestedproject1","project","/rootgroup1"
"nestedgroup1","group","/rootgroup1"
"nestednestedproject2","project","/rootgroup1/nestedgroup1"
"rootproject1","project","/"
"rootgroup2","group","/"

This differs in some respects from the sample output, but hopefully you can take it from here.

Upvotes: 2

Related Questions