Home > other >  how to jq by the desired key is inside nested json
how to jq by the desired key is inside nested json

Time:07-18

Here is the id.json

{
    "name": "peter",
    "path": "desktop/name",
    "description": "male",
    "env1": {
        "school": "AAA",
        "height": "150",
        "weight": "80"
    },
    "env2": {
        "school": "BBB",
        "height": "160",
        "weight": "70"
    }
}

it can be more env3, env4, etc created automatically I am trying to get the env1 by using height and weight as key so the output can look like:

env1:height:150
env1:weight:80
env2:height:160
env2:weight:70
env3:height:xxx
.
.
.

My shell command jq .env1.height... id.json tried can only get the output by using env1, env2 as key, but it cannot handle env3, env4. And also, using jq to_entries[] to convert the json defined by key and value, but the first few row made me cannot get .value.weight as output. Any idea please?

Update: edited the json to remove these three line

"name": "peter",
"path": "desktop/name",
"description": "male",

Then run below command:

jq 'to_entries[] | select(.value.height!=null) | [.key, .value.height, .value.weight]' id2.json 

I can get below result

[
  "dev",
  "1",
  "1"
]
[
  "sit",
  "1",
  "1"
]

This is almost what I need, but any idea to remove the outer level json please?

CodePudding user response:

Using your data as initially presented, the following jq program:

keys_unsorted[] as $k 
| select($k|startswith("env"))
| .[$k] | to_entries[]
| select(.key|IN("height","weight"))
| [$k, .key, .value]
| join(":")

produces

env1:height:150
env1:weight:80
env2:height:160
env2:weight:70

An answer to the supplementary question

According to one interpretation of the supplementary question, a solution would be:

keys_unsorted[] as $k 
| .[$k]
| objects
| select(.height and .weight)
| to_entries[]
| select(.key|IN("height","weight"))
| [$k, .key, .value]
| join(":")

Equivalently, but without the redundancy:

["height","weight"] as $hw
| keys_unsorted[] as $k 
| .[$k]
| objects 
| . as $object
| select(all($hw[]; $object[.]))
| $hw[]
| [$k, ., $object[.]]
| join(":")
  • Related