0

I am creating multiple files from a json template file and I need to replace two values in json file by different values which I am storing in variable. Below is how source json look like

Source :

{"parameters": [
            {
                "name": "dir_parm",
                "value": "changethis"
            }
        ],
        "targets": [
            {
                "identifier": "hsotchangethis"
            }
        ]

}

Output what I require:

"parameters": [
            {
                "name": "dir_parm",
                "value": "/apps"
            }
        ],
        "targets": [
            {
                "identifier": "iass02"
            }
      ]
   }

In this way json file has to be updated for directory and host name around 40-50 times.

Below is the sed command I tried but it is getting replaced. File name, hostname , directory all are variables\dynamic.

sed -i '/identifier/c\ \"identifier\" : '${bdhostnm}'/g' $fname

Note- I read we can use jq but in the organization it is not allowed. Any suggestion would be helpful

7
  • I am sorry, I mean sed command I used is not replacing host with the value in variable. It is either coming as empty or coming as bdhostnm Commented Aug 11, 2022 at 10:12
  • Have you tried using a tool, like jq, which is made especially for processing JSON? Commented Aug 11, 2022 at 10:29
  • jq is not available in the environment Commented Aug 11, 2022 at 10:35
  • Is python? Commented Aug 11, 2022 at 10:36
  • @user19742249, In case you can install jq, then following could be helpful to you: jq '.parameters[].value |= "/apps" | .targets[].identifier |= "iass02"' Input_file Commented Aug 11, 2022 at 11:17

2 Answers 2

3

As asked by user a sed solution:
Input

{"parameters": [
            {
                "name": "dir_parm",
                "value": "changethis"
            }
        ],
        "targets": [
            {
                "identifier": "hsotchangethis"
            }
        ]

}
value='/apps'  
bdhostnm='iass02'  
fname=file  
sed '/[ ]*"identifier":/{s/\("identifier": \)\(.*\)/\1'$bdhostnm'/g};/^[ ]*"value": /{s/\("value": \)\(.*\)/\1'${value/\//\\\/}'/g}' $fname
{"parameters": [
            {
                "name": "dir_parm",
                "value": /apps
            }
        ],
        "targets": [
            {
                "identifier": iass02
            }
        ]

}
Sign up to request clarification or add additional context in comments.

3 Comments

This is not working as expected
I get message sed: -e expression #1, char 98: extra characters after command and values are not getting repalced.
have you setted variables bdhosnm and value and fname
1

Since OP doesn't have jq and can't install jq so coming up with this awk solution. Which is written and tested in GNU awk. Here I have created 2 awk variables named valValue and valIdentifier where NEW values for respective(json) fields should be mentioned in them.

Here is the Online demo for used regex in following awk code.

awk -v valValue="/apps" -v valIdentifier="iass02" -v RS="" '
match($0,/^({"parameters": \[\n[[:space:]]+\
{\n[[:space:]]+"name": "dir_parm",\
\n[[:space:]]+"value": ")\
[^"]*("\n[[:space:]]+}\n\
[[:space:]]+\],\n[[:space:]]+\
"targets": \[\n[[:space:]]+\
{\n[[:space:]]+"identifier": ")\
[^"]*("\n[[:space:]]+}\n[[:space:]]+\
\]\n+[[:space:]]+})/,arr){
     print arr[1] valValue arr[2] valIdentifier arr[3]
}
'  Input_file

NOTE: In case someone wants a jq code for this one(though its clearly not a ask in question here), then try like: jq '.parameters[].value |= "/apps" | .targets[].identifier |= "iass02"' Input_file.

6 Comments

In case someone looking for one-liner form of awk code try like: awk -v valValue="/apps" -v valIdentifier="iass02" -v RS="" 'match($0,/^({"parameters": \[\n[[:space:]]+{\n[[:space:]]+"name": "dir_parm",\n[[:space:]]+"value": ")[^"]*("\n[[:space:]]+}\n[[:space:]]+\],\n[[:space:]]+"targets": \[\n[[:space:]]+{\n[[:space:]]+"identifier": ")[^"]*("\n[[:space:]]+}\n[[:space:]]+\]\n+[[:space:]]+})/,arr){print arr[1] valValue arr[2] valIdentifier arr[3]}' Input_file
value and target has to be modified as I have stored them in variables . json file has to be created for each target and value . When I try to valValue and valdentifier as variable , I am not getting results as expected.
@user19742249, both things could be done. Have awk like this: awk -v valValue="$value" -v valIdentifier="$idenifier" -v RS="" 'match($0,/^({"parameters": \[\n[[:space:]]+{\n[[:space:]]+"name": "dir_parm",\n[[:space:]]+"value": ")[^"]*("\n[[:space:]]+}\n[[:space:]]+\],\n[[:space:]]+"targets": \[\n[[:space:]]+{\n[[:space:]]+"identifier": ")[^"]*("\n[[:space:]]+}\n[[:space:]]+\]\n+[[:space:]]+})/,arr){print arr[1] valValue arr[2] valIdentifier arr[3]}' Input_file I have virialized this program now, where value and identifier both are shell variables passed to awk. Run this.
@user19742249, continuing above comment here: Run this and see output on terminal once you are Happy we can save output into file, let me know how it goes.
@user19742249, you need to create shell variables then pass them to awk program just want to be clear here.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.