通过Python编辑配置文件
我需要通过Python来编辑一个配置文件,我在StackOverflow和谷歌上搜索过,但没有找到适合我情况的解决方案,因为我需要替换文件中的多行内容,并且在搜索时要进行匹配。
我找到的内容主要是讲如何替换一行,但我至少需要替换8行,我想知道有没有比把10个replace(foo, bar)放在一起更简洁优雅的方法。
我需要“匹配”像“ENABLEPRINTER”、“PRINTERLIST”、“PRNT1.PORT”这样的行。我想匹配这些文本,并忽略后面的内容(例如:“=PRNT1, PRNT2”)。
所以我会做类似这样的事情:
replace('ENABLEPRINTER', 'y')
replace('PRINTERLIST', 'PRNT3)
文件的内容看起来是这样的:
ENABLEPRINTER=n
PRINTERLIST=PRNT1, PRNT2
PRNT1.PORT=9600
PRNT1.BITS=8
另外,这些文件大约有100行,我需要编辑其中大约10行。
非常感谢你的帮助。
更新:
使用@J.F. Sebastian发布的代码后,我现在遇到了以下错误:
configobj.ParseError: Parse error in value at line 611.
文件的第611行是:
log4j.appender.dailyRollingFile.DatePattern='.'yyyy-MM-d
所以问题出在'这个字符上。
如果我把那一行注释掉,使用@J.F. Sebastian发布的代码脚本就能正常工作。
2 个回答
如果文件是 java.util.Properties
格式的话,你可以使用 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'))
这个工具不是特别稳定,但一些修复可以帮助后面的人更好地使用。
如果你想在一个短字符串中多次替换内容:
for old, new in [('ENABLEPRINTER', 'y'), ('PRINTERLIST', 'PRNT3')]:
some_string = some_string.replace(old, new)
如果你想在配置文件中替换变量名(使用 configobj
模块):
import configobj
conf = configobj.ConfigObj('test.conf')
for old, new in [('ENABLEPRINTER', 'y'), ('PRINTERLIST', 'PRNT3')]:
conf[new] = conf[old]
del conf[old]
conf.write()
如果你说的 replace('ENABLEPRINTER', 'y')
是指把 y
赋值给 ENABLEPRINTER
变量,那么:
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()
看起来 configobj
和以下内容不兼容:
name = '.'something
你可以给它加上引号:
name = "'.'something"
或者:
name = '.something'
或者
name = .something
conf.update()
做的事情类似于:
for name, value in [('ENABLEPRINTER', 'y'), ('PRINTERLIST', 'PRNT3')]:
conf[name] = value
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()
之前:
ENABLEPRINTER=n
PRINTERLIST=PRNT1, PRNT2
PRNT1.PORT=9600
PRNT1.BITS=8
之后:
y=n
PRNT3==PRNT1, PRNT2
734=9600
PRNT1.BITS=8
这太简单了,不能算是一个完整的答案。请说说有哪些错误或不足之处。
正则表达式的好处在于它们可以很容易地根据特定情况进行调整。
.
编辑:
我刚刚看到:
"我想做的是给变量赋一个新值"
你早些时候就可以提到这一点的!
能否给一个文件的例子,展示一下修改前和修改后的内容?
.
编辑 2
这是用来更改文件中某些变量值的代码:
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)
之前:
ENABLEPRINTER=n
PRINTERLIST=PRNT1, PRNT2
PRNT1.PORT=9600
PRNT1.BITS=8
之后:
ENABLEPRINTER=y
PRINTERLIST=PRNT3
PRNT1.PORT=8310
PRNT1.BITS=8