Home > Blockchain >  How to dynamically update one json object and put it back into the original json objects?
How to dynamically update one json object and put it back into the original json objects?

Time:02-01

How to dynamically update one JSON object and put it back into the original JSON objects variable?

I have one variable with the following JSON data in it.

test='[
{
"Name": "James",
"Mobile": 12345678,
"Gender": "Male",
"Boolean": true,
"Pet":  "cat"
},
{
"Name": "John",
"Mobile": 1234567875,
"Gender": "Male",
"Boolean": true,
"Pet": "rat"
},
{
"Name": "Jennifer",
"Mobile": 1234567890,
"Gender": "Female",
"Boolean": true,
"Pet": "Dog"
},
{
"Name": "Julia",
"Mobile": 1234567890,
"Gender": "Female",
"Boolean": true,
"Pet": "Dog"
},
{
"Name": "Jeff",
"Mobile": 9871234567890,
"Gender": "Male",
"Boolean": true,
"Pet": "Fish"
},
{
"Name": "Jones",
"Mobile": 79871234567890,
"Gender": "Female",
"Boolean": true,
"Pet": "Parrot"
}
]'

items=$(echo "$test" | jq -c -r '.[]')
for item in ${items[@]}; do
    uName=$(echo $item | jq -r '.Name')
    if [ "$uName" == "John" ]; then
        echo "$item"
        echo " "
        modifiedTest=$(echo "$item" | jq  '.Name = "Tom"')
        modifiedTest=$(echo "$modifiedTest" | jq  '.Pet = "rabbit"')
        echo "$modifiedTest"
    fi    
done

Now let's say we have the below second JSON object from the above JSON objects

{
"Name": "John",
"Mobile": 1234567875,
"Gender": "Male",
"Boolean": true,
"Pet": "rat"
}

We have updated the above-picked JSON object fields with below

{
"Name": "Tom",
"Mobile": 1234567875,
"Gender": "Male",
"Boolean": true,
"Pet": "rabbit"
}

Now how can we add/update the above modified JSON object back into the original objects list variable 'test' at the exact position (2nd position in this case) but using a filter of 'Name=John' and in a dynamic way we don't know exact index position of this object using bash scripting?

CodePudding user response:

The tool jq can be used for JSON-manipulation:

jq '.[1].Name = "Tom" | .[1].Pet = "rabbit"' data.json

This will output the modified file on the console.

Note that in general jq [filter] data.json > data.json will not work and even when it seems to, overwriting the input file in this way should be avoided. One option would be to use a shell variable:

json_data=$(jq '.[1].Name = "Tom" | .[1].Pet = "rabbit"' data.json)
echo $json_data > data.json

Another option would be to use a temporary file; still another would be to use a utility such as sponge in .


Note that your shown file is not valid JSON and so jq will not be able to read it as JSON. To fix it, I have surrounded everything by [ and ] and removed the extra comma in the John object.

CodePudding user response:

What if we don't know the exact index position of this object and use a filter of 'Name=John'

< data.json jq '
  (map(.Name)| index("John")) as $ix 
  | (select($ix)
     | .[$ix] |= (.Name = "Tom" | .Pet = "rabbit")) // .
' | sponge data.json 

But you might want to backup data.json first.

  • Related