Редактировать файл конфигурации через Python - PullRequest
8 голосов
/ 14 марта 2011

Мне нужно отредактировать файл конфигурации через python, и я попытался выполнить поиск в stackoverflow и google, и они не охватывают мою ситуацию, поскольку мне нужно заменить строки в файле и выполнить совпадения в моем поиске.

Кроме того, то, что я нашел, охватывает, как сделать это для одной строки, я буду выполнять по крайней мере 8 замен строк в файле, и я хотел бы знать, есть ли более чистый и более элегантный способ сделать это, чем положить 10 заменить (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 из них.

Большое спасибо за вашу помощь.

UPDATE

Использование кода, отправленного @ J.F. Себастьян, сейчас я получаю следующую ошибку:

configobj.ParseError: Parse error in value at line 611.

Строка 611 файла:

log4j.appender.dailyRollingFile.DatePattern='.'yyyy-MM-d

Так что проблема в символе '.

Если я закомментирую эту строку, скрипт работает нормально с кодом, размещенным @ J.F. Себастьян.

Ответы [ 2 ]

7 голосов
/ 15 марта 2011
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

Слишком просто, чтобы быть окончательным. Скажите, в чем ошибки или слабости.

Преимущество регулярных выражений в том, что их можно легко модулировать в конкретных случаях.

.

EDIT:

Я только что видел это:

«что я хочу сделать, это присвоить новое значение переменной»

Вы могли бы сообщить об этом раньше!

Не могли бы вы дать пример файла до / после, пожалуйста.

.

РЕДАКТИРОВАТЬ 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
4 голосов
/ 14 марта 2011

Если файл в формате 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 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()

Если под 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
...