Assuming that your JSON document is well formed, which the example that you show is not as it contains multiple issues:
$ cat file { "root": { "instances": [ { "name": "1", "configs": [ { "keyname": "foo", "value": "" }, { "keyname": "barrr", "value": "barrrr" } ] }, { "name": "2", "configs": [ { "keyname": "foo", "value": "" }, { "keyname": "buzzz", "value": "buzzz" } ] } ] } }
$ jq '( .root.instances[].configs[] | select(.keyname == "foo") ).value = "foo"' file { "root": { "instances": [ { "name": "1", "configs": [ { "keyname": "foo", "value": "foo" }, { "keyname": "barrr", "value": "barrrr" } ] }, { "name": "2", "configs": [ { "keyname": "foo", "value": "foo" }, { "keyname": "buzzz", "value": "buzzz" } ] } ] } }
This jq expression updates the value of the .value key to the string foo. The key that is updated is selected from one of the entries in .root.instances[].configs[]. Note that .root.instances is an array and that each .configs entry in each of its elements is also an array. The select() statement tests the .keyname key with the string foo.
Making the query key and new value variable is done as follows:
jq --arg querykey 'foo' \ --arg newval 'The train said "choo choo"' \ '( .root.instances[].configs[] | select(.keyname == $querykey) ).value = $newval' file
This creates two internal jq variables called $querykey and $newval. Their values will be appropriately encoded so that e.g. $newval can contain double quotes, as shown above.