nick01
nick01

Reputation: 333

writing a subset of source ini file into destination ini file

I have source.ini as following

[section1]
name = 'xyz'
place = 'abc'

[section2]
....
....

[section3]
....
....

I want to read the source.ini and copy contents of only list of sections into a new ini file. Here's my code doing the needful..

import ConfigParser

Config = ConfigParser.RawConfigParser()
Config.read('source.ini')
sections = ['section1', 'section2']

outputConfig = ConfigParser.RawConfigParser()

with open('destination.ini', 'wb') as fp:
    for each_section in sections:
        fp.write('\n\n['+each_section+']\n')
        for (each_key, each_val) in Config.items(each_section):
            fp.write(each_key+':'+each_val+'\n')

        outputConfig.write(fp)

I'm getting the output as desired. My question is am I doing it the right way? IS there a more elegant way to do this?

Upvotes: 0

Views: 114

Answers (2)

Robᵩ
Robᵩ

Reputation: 168646

Yes, your code is inelegant. It writes the output file twice. First, by hand:

fp.write(each_key+':'+each_val+'\n')

and second, with the help of the RawConfigParser object:

outputConfig.write(fp)

Only the manual write is effective. The call to outputConfig.write() is a no-op.

We should eliminate one of the two methods of creating the output file, but which one? I claim the manual method should be removed, since your program otherwise doesn't need to have intimate knowledge of the .INI file format.

Also, I find your use of each_ to represent loop variables disconcerting. Maybe its just a personal preference.

Here is how I would fix it:

import ConfigParser

Config = ConfigParser.RawConfigParser()
Config.read('source.ini')
sections = ['section1', 'section2']

outputConfig = ConfigParser.RawConfigParser()

for section in sections:
    outputConfig.add_section(section)
    for key, val in Config.items(section):
        outputConfig.set(section, key, val)


with open('destination.ini', 'w') as fp:
    outputConfig.write(fp)

Upvotes: 1

Serge Ballesta
Serge Ballesta

Reputation: 148975

Independantly of the answer of Rob, there may some other problems with your approach. First, you use a RawConfigParser. It is correct under Python 2.x, but for 3.x, it is considered as legacy and ConfigParser would be recommended.

But IMHO, the main problem is that the configparser module will strip any comment from your file if you have some and want to keep them. Here is a variant using regex that will keep comments provided they are either at beginning of file or after a valid [section] :

import re

sections = ['section1', 'section2']
rxsect = re.compile('^\s*\[\s*(\w+)\s*\]')
with open('source.init') as fin, open('destination.ini', 'w') as fout:
    copy = True
    for line in fin:
        m = rxsect.match(line)
        if m:
            copy = m.group(1) in sections
        if copy:
            n = fout.write(line)

Of course, if comments are not a concern, Rob's answer is better because the file is parsed and syntax errors would be detected, while mine assumes the file is syntaxically correct.

Upvotes: 1

Related Questions