3

We have a sample .cfg file consist of key value pair. Based on user input, we need to update the value. I was thinking to update the value using configParser but file doesn't have any section (e.g. [My Section]). Based on the documentation it needs three values to set - section, key and value. Unfortunately, I will not be able to add any section marker, as this file is used by other tasks.

What would be the another way we can set the value based on key?

File example

some.status_file_mode    =  1    # Some comment
some.example_time    = 7200     # Some comment 

As per the requirement, no change in the line. Spaces and comments needs to be same as is.

2
  • Now you have changed your input. Please don't do that. Commented Mar 6, 2018 at 3:57
  • My bad, I missed the comment section earlier. I upvoted the earlier answer though. Commented Mar 6, 2018 at 4:00

2 Answers 2

3

Use NamedTemporaryFile from the tempfile module it is not too hard to build a simple parser to update a file that looks like that:

Code:

def replace_key(filename, key, value):
    with open(filename, 'rU') as f_in, tempfile.NamedTemporaryFile(
            'w', dir=os.path.dirname(filename), delete=False) as f_out:
        for line in f_in.readlines():
            if line.startswith(key):
                line = '='.join((line.split('=')[0], ' {}'.format(value)))
            f_out.write(line)

    # remove old version
    os.unlink(filename)

    # rename new version
    os.rename(f_out.name, filename)

Test Code:

import os
import tempfile
replace_key('file1', 'some.example_time', 3)

Results:

some.status_file_mode    = 1
some.example_time    = 3
Sign up to request clarification or add additional context in comments.

Comments

1

If you don't care about spacing, this works well for your case.

def replace_config(filename, key, value):
    d = {}
    with open(filename, "r+") as f:
        for line in f:
            k, v = line.split('=')
            c = ""
            try:
                v, c = v.split('#')
            except ValueError:
                c = ""
            d[k.strip()] = {'v': v.strip(), 'c': c.strip()}
        f.seek(0)
        f.truncate()
        d[key]['v'] = value
        for k, v in d.items():
            if v["c"]:
                text = "{} = {}    # {}\n".format(k, v['v'], v['c'])
            else:
                text = "{} = {}\n".format(k, v['v'])
            f.write(text)

replace_config('config.cfg', 'some.example_time', 3)

2 Comments

Thanks Rahul, I will try and let you know.
Sure, i will try it tomorrow and if it works will upvote as well. thanks again.

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.