art vanderlay
art vanderlay

Reputation: 2463

jq save value of nested key into var

With thanks to @peak with the linked question I have started to understand jq, but I am struggling with the basics of how to capture the output to vars in bash. reviewing the jq manual has not cleared things up

given the json below I would like to use walk to capture the value of a nested key. The structure is unknown prior to execution, so a standard query is not possible and the needed key can be a arbitrary nested level deep from 0 to 20.

sample json

{
    "zzz": [{
        "id": "aaa",
        "des": "object A",
        "parent": "zzz",
        "children": {
            "aaa": [{
                "id": "bbb",
                "des": "object B",
                "parent": "aaa",
                "children": {
                    "bbb": [{
                        "id": "ccc",
                        "des": "object C",
                        "parent": "bbb",
                        "children": {
                            "ccc": [{
                                "id": "ddd", <===this is the value I need
                                "des": "object d",
                                "parent": "ccc"
                            }]
                        }
                    }, {
                        "id": "eee",
                        "des": "object e",
                        "parent": "bbb"
                    }]
                }
            },{
                "id": "fff",
                "des": "object f",
                "parent": "aaa"
            }]
        }
    }]} 

now using the walk function I can locate the key I want

myId=$(jq 'walk(when(type == "object";
                            with_entries(
                            when(.key|test("ccc");
                            when(any(.value[]; .parent == "ccc");
                                ...insert action-code here....
                                )))))' <<< ${json})

If I use the walk code above and have an action code like .value[] += {"myKey": "myVal"} it will add it to the selected object.

Now I want to capture the value of id not add to the object. So I though it would be a simple string or perhaps a select statement but they do not work.

action-code

select(.parent == "ccc")|.hrn|.value
or
.hrn.value
or
.value[].hrn?

plus a lot of other combinations. What is the correct syntax to capture the id value?

Upvotes: 0

Views: 177

Answers (1)

peak
peak

Reputation: 116670

For this type of problem, you can use ... With your data as input, the following filter:

..
| objects
| to_entries[]
| select(.key|test("ccc"))
| .value[]
| select(.parent=="ccc")
| .id

produces:

"ddd"

Upvotes: 1

Related Questions