Jq: `recurse()`, but preserve structure

Created on 4 Jan 2014  路  7Comments  路  Source: stedolan/jq

Let's take the recurse example from the manual, and add a bunch of useless {"foo": "bar"} to it:

{"name": "/", "foo": "bar", "children": [
  {"name": "/bin", "foo": "bar", "children": [
    {"name": "/bin/ls", "foo": "bar", "children": []},
    {"name": "/bin/sh", "foo": "bar", "children": []}]},
  {"name": "/home", "foo": "bar", "children": [
    {"name": "/home/stephen", "foo": "bar", "children": [
      {"name": "/home/stephen/jq", "foo": "bar", "children": []}]}]}]}

recurse(.children[]) | .name will give me all the names, but destroy the structure of the JSON in the process.

Is there a way to get that information, but preserve the structure?

With the JSON above, this would be the output:

{"name": "/", "children": [
  {"name": "/bin", "children": [
    {"name": "/bin/ls", "children": []},
    {"name": "/bin/sh", "children": []}]},
  {"name": "/home", "children": [
    {"name": "/home/stephen", "children": [
      {"name": "/home/stephen/jq", "children": []}]}]}]}
support wiki

Most helpful comment

I was lurking through the query label and found this issue. Better late than never, I guess!

In order to remove the "foo" attribute from each element of the structure, you want to recurse through the structure and set each element to the result of deleting the foo attribute from itself. This translates to jq as:

recurse(.children[]) |= del(.foo)

If, instead of blacklisting foo, you'd rather whitelist name and children, you could do something like:

recurse(.children[]) |= {name, children}

All 7 comments

@1ace You want to remove keys that are not of interest, is that it?

I was lurking through the query label and found this issue. Better late than never, I guess!

In order to remove the "foo" attribute from each element of the structure, you want to recurse through the structure and set each element to the result of deleting the foo attribute from itself. This translates to jq as:

recurse(.children[]) |= del(.foo)

If, instead of blacklisting foo, you'd rather whitelist name and children, you could do something like:

recurse(.children[]) |= {name, children}

@slapresta That's a neat idiom we should add to the wiki. Thanks!

I think we can close this, but I don't have permission to do so.

I left it open because I haven't checked whether the wiki mentions this, and it's worth making sure it does.

The idioms are described at
https://github.com/stedolan/jq/wiki/jq-Cookbook#delete-elements-from-objects-recursively

Thanks :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rokka-n picture rokka-n  路  4Comments

tischwa picture tischwa  路  4Comments

rclod picture rclod  路  4Comments

sonots picture sonots  路  3Comments

kaihendry picture kaihendry  路  4Comments