0

I have json file with lot of comments inside file. I want to replace only specific values and save the results by saving the structure and formatting in a json file.

For example in this part:

  "blocks" : [
{
  "block_name" : "PNS1",
  "ip" : "192.168.1.142",
  "dynamic_ports" : { "first" : 10000, "last" : 15000 },
  "inherits" : "PNS",
  "in" : [],
  "out" : [
    /* Отправка данных в другой коллектор */
    { "name" : "collector_data_out", "dest_port" : "collector_data_in", "dest_block" : "PNS2", "fifo" : true },
    /* Отправка темперутры, давлений и тарировок в СВС */
    { "name" : "svs_ctrl_out", "dest_port" : "svs_ctrl_in", "dest_block" : "SELF,MFI1,MODEL", "fifo" : true },
    /* Отправка данных для определения главного транзитора */
    { "name" : "another_transitor_out", "dest_port" : "another_transitor_in", "dest_block" : "PNS2", "fifo" : true }
  ]
},

All i want to replace is in blocks -> ip. So it must be like this:

"ip" : "127.0.0.1",

Here is the original json file: https://pastebin.com/Neumxy4p

How can i do this via python json?

4
  • Do you want those comments to stay in your file once modified ? Commented Jul 2, 2020 at 13:22
  • FWIW, if it has comments, it's not (valid) JSON… Commented Jul 2, 2020 at 13:25
  • @Leogout yes, comments needs to stay Commented Jul 2, 2020 at 13:38
  • @a.wise Is there an id key for every dict in blocks? Commented Jul 2, 2020 at 13:42

5 Answers 5

3

Your JSON file contains comment which is not considered valid JSON and will fail to load if tried using json.load or json.loads.
I've used positive lookahead and positive lookbehind to match you IP address and replaced it with 127.0.0.1.

import re

with open('your_file_name.json') as fp:
    file_content = (fp.read())

file_content = re.sub(r'(?<="ip"[\s]:[\s]")[\d.]+(?=",)', "127.0.0.1", file_content)
Sign up to request clarification or add additional context in comments.

Comments

0

From what I understood, you need to replace your IP with some custom value.

If you want to do it immutably, try this

blocks = [{**item, "ip": "127.0.0.1"} for item in blocks]

If mutations are not an issue, just

for block in blocks:
    block["ip"] = "127.0.0.1"

Comments

0

Here is one solution to your problem:

with open(jsonPath) as file:
    json= json.load(file)
    file.close()
for block in json["blocks"]:
    block["ip"] = "127.0.0.1"

3 Comments

It's not right to name a variable a module you imported. You don't need to close a file if you have with.
So which element do you want to change the property 'ip' of?
the op wants to change all
0

Here is what you can do:

import json

with open('file.json', 'r') as r:
    dct = json.load(r) # Load the dct from the json file

for d in dct["blocks"]: # For every dict in the `blocks` list
    d["ip"] = "127.0.0.1" # Update that dict

with open('file.json', 'w') as w:
    json.dump(r, w) # Dump the updated dict into the json file

Comments

0

I would simply do :

with open('file.json', 'r') as f:
    content = f.read()
ip_to_insert = "127.0.0.1"
p0 = 0
while content.find('"ip" : "', p0) > 0:
    p0 = content.find('"ip" : "') + len('"ip" : "')
    p1 = content.find('"', p0)
    # replace what is between index p0 and p1 :
    content = content[:p0] + ip_to_insert + content[p1:]
print(content)

As this json file is commented, python json may not be able to read it, moreover, playing with json only to replace one type of value if overkill. The method stated above may not be the shortest nor the fastest, but is more adapted in this case (or so I believe). If you're not sure about spaces in "ip" : ", you can always go around with regex (re).

Comments

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.