dks551
dks551

Reputation: 1113

Update field inside a nested JSON object based on key using jq

I have a json file with the below format

{
    "l1":"",
    "values":{
        "id1":{
            "name":"abc",
            "enabled":"true"

        },
        "id2":{
            "name":"def",
            "enabled":"true"
        },
        "id3":{
            "name":"jjj"
        }
    }
}

I want to add/update the enabled status of the json object based on the parent key. so,eg: I have a file with below contents.

id1 false
id2 true
id3 false
id4 false

I want my output to look like below:

{
    "l1":"",
    "values":{
        "id1":{
            "name":"abc",
            "enabled":"false"

        },
        "id2":{
            "name":"def",
            "enabled":"true"
        },
        "id3":{
            "name":"jjj",
            "enabled":"false"
        }
    }
}

jq version:1.5

Upvotes: 1

Views: 618

Answers (2)

peak
peak

Reputation: 116987

This response addresses the issue regarding the conversion of the true/false text file to JSON. That could be achieved in a stand-alone fashion by piping the text file to:

jq -nR '
  ([inputs |capture("(?<key>.*) (?<value>(true|false)) *$")
    | select(.value | fromjson | type == "boolean") ]
    | from_entries)'

Or, better, @JeffMercado's filter can be combined with the above, e.g. like so:

jq -nR --argfile in input.json '
  ([inputs |capture("(?<key>.*) (?<value>(true|false)) *$")
    | select(.value | fromjson | type == "boolean") ]
   | from_entries) as $dict
  | $in
  | .values |= with_entries(.value.enabled = $dict[.key])                   
'       

(Yes, --argfile has been deprecated, so feel free to use your preferred alternative.)

If you wanted enabled to be boolean (i.e., true or false), you could simply add | map_values(fromjson) immediately after the call to from_entries.

Upvotes: 0

Jeff Mercado
Jeff Mercado

Reputation: 134601

You can just create a mapping of the ids you want to update and the value to update to. Then use that mapping to update the corresponding values.

$ jq --argjson m '{"id1":"false","id2":"true","id3":"false","id4":"false"}' '
.values |= with_entries(.value.enabled = $m[.key])
' input.json

Upvotes: 1

Related Questions