skip to Main Content

Using JSON format, for bookmarks in my case, it’s nice to able to clean them and retain only useful (a list of named) attributes (these occur at all levels of the structure).
As output, the whole JSON hierarchy has to be preserved.

Can that be done using the "JQ" tool?

So far, I have only been able to name attributes to be removed:

jq -c 'del(..| .index?,.guid?,.id?,.dateAdded?,.lastModified?,.typeCode?,.iconUri?)' in.json >out.json

The need is to specify the attributes to be kept, instead : e.g. {children,type,root,title,uri}.

Can one use the del() function and somehow "negate" this list, or use select() while recursing? I tried some combos but all failed.

Note that the "children" attribute has a special role in this example, as it defines JSON subtrees, but I hope for a solution in which it is treated just as other attributes.

(Extra question: is it possible to combine this with depth filtering, e.g. only when depth>3?)

Sample input JSON :

{
  "guid": "toolbar_____",
  "title": "toolbar",
  "type": "text/x-moz-place-container",
  "children": [
    {
      "guid": "Y-lVXPFXlF15",
      "title": "",
      "iconUri": "https://fr.wikipedia.org/static/apple-touch/wikipedia.png",
      "type": "text/x-moz-place",
      "uri": "https://fr.wikipedia.org/"
    },
    {
      "guid": "S7ow_jYLOBlX",
      "title": "tmp",
      "type": "text/x-moz-place-container",
      "children": [
        {
          "guid": "IFQ7EJXc-eNH",
          "title": "Logiciel Attentes",
          "type": "text/x-moz-place-container",
          "children": [
            {
              "guid": "l-CtLEfkIatC",
              "title": "LMMS v122",
              "iconUri": "https://lmms.io/img/logo_sm.png",
              "type": "text/x-moz-place",
              "uri": "https://lmms.io/download#collapse_linpre"
            },
            {
              "guid": "a5HfcSy3k_sT",
              "title": "Slax UEFI apres v9.11",
              "type": "text/x-moz-place",
              "uri": "https://www.slax.org/"
            }
          ]
        },
        {
          "guid": "FUt5BsHdDl2Y",
          "title": "Firewalls – MX Linux",
          "type": "text/x-moz-place",
          "uri": "https://mxlinux.org/wiki/networking/firewalls/"
        }
      ]
    }
  ]
}

Expected output :

{
  "title": "toolbar",
  "type": "text/x-moz-place-container",
  "children": [
    {
      "title": "",
      "type": "text/x-moz-place",
      "uri": "https://fr.wikipedia.org/"
    },
    {
      "title": "tmp",
      "type": "text/x-moz-place-container",
      "children": [
        {
          "title": "Logiciel Attentes",
          "type": "text/x-moz-place-container",
          "children": [
            {
              "title": "LMMS v122",
              "type": "text/x-moz-place",
              "uri": "https://lmms.io/download#collapse_linpre"
            },
            {
              "title": "Slax UEFI apres v9.11",
              "type": "text/x-moz-place",
              "uri": "https://www.slax.org/"
            }
          ]
        },
        {
          "title": "Firewalls – MX Linux",
          "type": "text/x-moz-place",
          "uri": "https://mxlinux.org/wiki/networking/firewalls/"
        }
      ]
    }
  ]
}

2

Answers


  1. You could walk through the structure, and update all objects by using with_entries to temporarily convert them into an array of key-value pairs, and filter them for those entries with matching keys (i.e. select it if its .key is IN a given list of positives).

    walk(objects |= with_entries(select(IN(.key;
      "children", "type", "root", "title", "uri"
    ))))
    

    Demo

    Extra question : is it possible to combine this with depth filtering, e.g. only when depth>3

    You could apply the above to only those at your desired depth:

    .[]?[]?[]? |= walk(…)
    
    Login or Signup to reply.
  2. Here is a way:

    delpaths([
      paths | select(
        length > 3 and (
          last | type != "number" and (IN(
            "children", "type",
            "root", "title", "uri"
          ) | not)
        )
      )
    ])
    

    Online demo

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