Reputation: 333
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
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
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