Venu Reddy
Venu Reddy

Reputation: 49

Find a key-value anywhere in JSON file and replace key with a variable

I need to replace the value of "JaegerAgentHost" with a variable that I already have.

I have multiple formats of JSON on each app.

APP1 JSON file:

{
"Settings": {
"JaegerServiceSettings": {
"JaegerAgentHost": "jaeger.apps.internal",
"JaegerAgentPort": "6831"
} } }

APP2 JSON file:

{
"JaegerServiceSettings": {
"JaegerAgentHost": "jaeger.apps.internal",
"JaegerAgentPort": "6831",
} }

App3 JSON file:

{
"JaegerAgentHost": "jaeger.apps.internal",
"JaegerAgentPort": "6831"
}

irrespective of the path of key-value of JaegerAgentHost, I should be able to replace the value of it with my variable that ultimately should become as below

expected output::

APP1 JSON file:

{
"Settings": {
"JaegerServiceSettings": {
"JaegerAgentHost": "jaeger.app",
"JaegerAgentPort": "6831"
} } }

APP2 JSON file:

{
"JaegerServiceSettings": {
"JaegerAgentHost": "jaeger.app",
"JaegerAgentPort": "6831",
}}

App3 JSON file:

{
"JaegerAgentHost": "jaeger.app",
"JaegerAgentPort": "6831"
}

Please advice how we can do it, when I have multiple JSON files like to find and replace the perticular key-value with jq and bash

As of now I have multiple command for each json file to replace, which is not best practice.

This is blocking me from making a common script for all.

I can use sed but worried about the structure changes that may happen to any of the JSON file as they were not uniform and would like to prefer jq.

Upvotes: 1

Views: 758

Answers (1)

peak
peak

Reputation: 116977

One way would be to use walk.

Assuming $host holds the desired value, the jq filter would be:

walk(if type == "object" and has("JaegerAgentHost")
     then .JaegerAgentHost = $host else . end)

An alternative would be to use .. and |=:

(..|objects|select(.JaegerAgentHost).JaegerAgentHost) |= $host

You could pass in the value using the --arg command-line option, e.g.

   jq --arg host jaeger.app .....

Upvotes: 3

Related Questions