jsonjqobject-slicing

How to remove unnecessary items from an JSON with JQ?


I need from this: (example)

{
  "jobs": [
      {},
      {}
    ],
  "services": {
    "service-1": {
      "version": "master"
    },
    "service-2": {
      "foo": true,
      "version": "master"
    },
    "service-3": {
      "bar": "baz"
    }
  }
}

Make this:

{
  "services": {
    "service-1": {
      "version": "master"
    },
    "service-2": {
      "version": "master"
    }
  }
}

So delete all except .services.*.version. Help please, can't handle it with my knowledge of the JQ.


Solution

  • Translating your expression .services.*.version quite generically, you could use tostream as follows:

    reduce (tostream
            | select(length==2 and
                     (.[0] | (.[0] == "services" and
                              .[-1] == "version")))) as $pv (null;
        setpath($pv[0]; $pv[1]) )
    

    Using jq's streaming parser

    To reduce memory requirements, you could modify the above solution to use jq's streaming parser, either with reduce as above, or with fromstream:

    jq -n --stream -f program.jq input.json
    

    where program.jq contains:

    fromstream(inputs
        | select( if length == 2
                  then .[0] | (.[0] == "services" and
                               .[-1] == "version")
                  else . end ) )
    
    

    .services.*.version.*

    Interpreting .services.*.version more broadly so as not to require the terminal component of the path to be .version, simply replace .[-1] == "version" with:

    index("version")
    

    in the above.