Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 1, 2011 12:52:22

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

Парсинг конфигурационного файла. regexp или другое

aivs
s0rg
Это да - но нужно сохранить первоначальную структуру данных.
Именно так!
Мой пример и тот что выше выдают результат одинаковый, с той же структурой.

Офлайн

#2 Ноя. 2, 2011 22:27:05

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Парсинг конфигурационного файла. regexp или другое

Угу, со словарем будет быстрее и красивее.



Офлайн

#3 Ноя. 3, 2011 07:02:54

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Парсинг конфигурационного файла. regexp или другое

o7412369815963
Ed
Можете показать вариант со словарем с возможностью редактирования произвольного элемента и сохранением структуры?

Офлайн

#4 Ноя. 3, 2011 09:11:26

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Парсинг конфигурационного файла. regexp или другое

Его уже показал o7412369815963, разве нет.
На всякий случай продублирую:

from os import linesep, rename

fname = 'rc.conf'
new_name = '%s.new' % fname
repl = {"interface": "eth0", "address": "192.168.1.100", "netmask": "255.255.255.0", "gateway": "192.168.1.1"}

with open(fname) as inf, open(new_name, 'w') as outf:
for line in inf:
name = line.split('=')[0].split()
if name in repl:
line = "%s=%s%s" % (name, repl[name], linesep)
outf.write(line)
rename(new_name, fname)



Офлайн

#5 Ноя. 3, 2011 09:14:33

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Парсинг конфигурационного файла. regexp или другое

Не то - здесь элементы задаются в repl, то есть если нужно будет изменить другой элемент - то нужно будет руками в исходнике изменять этот словарь.
Я имел ввиду изменение произвольного элемента.
Просто задача манипуляции с конфигами довольно-таки частая, я привел в пример свой велосипед )
Но если есть реально более быстрые и красивые варианты - с удовольствием на них посмотрю.

Отредактировано (Ноя. 3, 2011 09:16:53)

Офлайн

#6 Ноя. 3, 2011 09:21:00

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Парсинг конфигурационного файла. regexp или другое

Не понял. Вариант со словарем отличается от моего изначального только в лучшую сторону. И в том и в другом если понадобится нечто другое заменять нужно править исходник. Или вы о другом?



Отредактировано (Ноя. 3, 2011 09:22:10)

Офлайн

#7 Ноя. 3, 2011 09:30:43

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Парсинг конфигурационного файла. regexp или другое

Предположим что появилась необходимость изменять данные в конфиге в зависимости от каких-либо условий, например:

cat my.conf

PARAM1 = 'a'
PARAM2 = 'b'

[ПСЕВДОКОД]

if conf['PARAM1'] == 'a':
conf['PARAM2'] = 'c'
else:
conf['PARAM2'] = 'd'

Отредактировано (Ноя. 3, 2011 09:31:03)

Офлайн

#8 Ноя. 3, 2011 09:42:38

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Парсинг конфигурационного файла. regexp или другое

Все равно не понимаю. Вынесите код в функцию, сделайте repl параметром и меняйте его когда угодно, в чем проблема?



Офлайн

#9 Ноя. 3, 2011 09:49:33

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Парсинг конфигурационного файла. regexp или другое

То есть вы предлагаете такой алгоритм:
1. Читаем файл, выкидываем комментарии и сплитим на ключ/значение.
2. Проверяем нужное значение, на основании его создаем repl.
3. Еще раз с начала проходим файл сверяя ключи, и если есть замена в repl то меняем.

?

Некрасиво как-то.

Отредактировано (Ноя. 3, 2011 09:50:18)

Офлайн

#10 Ноя. 3, 2011 09:53:35

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

Парсинг конфигурационного файла. regexp или другое

Зачем так странно делать? Нет, я предлагаю что-то типа такого:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
from os import linesep, rename

def update(fname, repl):

new_name = '%s.new' % fname

with open(fname) as inf, open(new_name, 'w') as outf:
for line in inf:
name = line.split('=')[0].strip()
if name in repl:
line = "%s=%s%s" % (name, repl[name], linesep)
outf.write(line)
rename(new_name, fname)

return 0

def main(argv):
fname = argv[1]
params = argv[2:]
return update(fname, dict(zip(params[::2], params[1::2])))

if __name__ == '__main__':
sys.exit(main(sys.argv))
Запускать например так:
./updater.py rc.conf interface eth0 address 192.168.1.100 netmask 255.255.255.0 gateway 192.168.1.1
PS: Естетственно парсинг и валидация параметров отсутствует, это чисто чтобы идею показать.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version