Home > Software engineering >  Find a key-value anywhere in JSON file and replace key with a variable
Find a key-value anywhere in JSON file and replace key with a variable

Time:03-24

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.

CodePudding user response:

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 .....
  • Related