skip to Main Content

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?

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search