可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I need to edit a configuration file through python and i tried searching on stackoverflow and google and they don't cover my situation, since i need to replace lines in the file and perform matches in my search.
Also, what i found covers how to do it for one line, i will be performing at least 8 line replacements in the file and I would like to know if there is a cleaner and more elegant way of doing this than putting 10 replace(foo, bar) lines altogether.
I need to "match" lines like "ENABLEPRINTER", "PRINTERLIST", "PRNT1.PORT".
I want to match thesse text and ignore whatever follows (ex: "=PRNT1, PRNT2").
So i would do something like
replace('ENABLEPRINTER', 'y')
replace('PRINTERLIST', 'PRNT3)
The file looks like this:
ENABLEPRINTER=n
PRINTERLIST=PRNT1, PRNT2
PRNT1.PORT=9600
PRNT1.BITS=8
Also note these files are about 100 lines and i need to edit about 10 of them.
Thank you very much for your help.
UPDATE:
Using the code posted by @J.F. Sebastian, i'm now getting the following error:
configobj.ParseError: Parse error in value at line 611.
Line 611 of the file is:
log4j.appender.dailyRollingFile.DatePattern='.'yyyy-MM-d
So the problem is with the ' character.
If I comment out that line, the script is working fine with the code posted by @J.F. Sebastian.
回答1:
import re
pat = re.compile('ENABLEPRINTER|PRINTERLIST|PRNT1.PORT')
def jojo(mat,dic = {'ENABLEPRINTER':'y',
'PRINTERLIST':'PRNT3',
'PRNT1.PORT':'734'} ):
return dic[mat.group()]
with open('configfile','rb+') as f:
content = f.read()
f.seek(0,0)
f.write(pat.sub(jojo,content))
f.truncate()
Before:
ENABLEPRINTER=n
PRINTERLIST=PRNT1, PRNT2
PRNT1.PORT=9600
PRNT1.BITS=8
After:
y=n
PRNT3==PRNT1, PRNT2
734=9600
PRNT1.BITS=8
Too simple to be definitive. Say what are the errors or weaknesses.
The advantage of regexes is they can be modulated easily to particular cases.
.
EDIT:
I've just seen that:
"what i want to do is assign a new value to the variable "
you could inform of that earlier !
Could you give an exemple of file before / after , please.
.
EDIT 2
Here's the code to change the values of certain variables in a file:
import re
from os import fsync
def updating(filename,dico):
RE = '(('+'|'.join(dico.keys())+')\s*=)[^\r\n]*?(\r?\n|\r)'
pat = re.compile(RE)
def jojo(mat,dic = dico ):
return dic[mat.group(2)].join(mat.group(1,3))
with open(filename,'rb') as f:
content = f.read()
with open(filename,'wb') as f:
f.write(pat.sub(jojo,content))
#-----------------------------------------------------------
vars = ['ENABLEPRINTER','PRINTERLIST','PRNT1.PORT']
new_values = ['y','PRNT3','8310']
what_to_change = dict(zip(vars,new_values))
updating('configfile_1.txt',what_to_change)
Before:
ENABLEPRINTER=n
PRINTERLIST=PRNT1, PRNT2
PRNT1.PORT=9600
PRNT1.BITS=8
After:
ENABLEPRINTER=y
PRINTERLIST=PRNT3
PRNT1.PORT=8310
PRNT1.BITS=8
回答2:
If the file is in java.util.Properties
format then you could use pyjavaproperties
:
from pyjavaproperties import Properties
p = Properties()
p.load(open('input.properties'))
for name, value in [('ENABLEPRINTER', 'y'), ('PRINTERLIST', 'PRNT3')]:
p[name] = value
p.store(open('output.properties', 'w'))
It is not very robust, but various fixes for it could benefit people who come next.
To replace multiple times in a short string:
for old, new in [('ENABLEPRINTER', 'y'), ('PRINTERLIST', 'PRNT3')]:
some_string = some_string.replace(old, new)
To replace variables names in a configuration file (using configobj
module):
import configobj
conf = configobj.ConfigObj('test.conf')
for old, new in [('ENABLEPRINTER', 'y'), ('PRINTERLIST', 'PRNT3')]:
conf[new] = conf[old]
del conf[old]
conf.write()
If by replace('ENABLEPRINTER', 'y')
you mean assign y
to the ENABLEPRINTER
variable then:
import configobj
ENCODING='utf-8'
conf = configobj.ConfigObj('test.conf', raise_errors=True,
file_error=True, # don't create file if it doesn't exist
encoding=ENCODING, # used to read/write file
default_encoding=ENCODING) # str -> unicode internally (useful on Python2.x)
conf.update(dict(ENABLEPRINTER='y', PRINTERLIST='PRNT3'))
conf.write()
It seems configobj
is not compatible with:
name = '.'something
You could quote it:
name = "'.'something"
Or:
name = '.something'
Or
name = .something
conf.update()
does something similar to:
for name, value in [('ENABLEPRINTER', 'y'), ('PRINTERLIST', 'PRNT3')]:
conf[name] = value