Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 19, 2011 09:40:28

aivs
От:
Зарегистрирован: 2011-05-26
Сообщения: 42
Репутация: +  0  -
Профиль   Отправить e-mail  

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

Есть конфигурационный файл rc.conf из Arch Linux

#
# /etc/rc.conf - Main Configuration for Arch Linux
#

# -----------------------------------------------------------------------
# LOCALIZATION
# -----------------------------------------------------------------------
LOCALE="ru_RU.UTF-8"
HARDWARECLOCK="localtime"
TIMEZONE="Europe/Moscow"
KEYMAP="us"
CONSOLEFONT=ter-u16b
CONSOLEMAP=
USECOLOR="yes"

# -----------------------------------------------------------------------
# HARDWARE
# -----------------------------------------------------------------------
MOD_AUTOLOAD="yes"
MODULES=()

# Scan for LVM volume groups at startup, required if you use LVM
USELVM="no"

# -----------------------------------------------------------------------
# NETWORKING
# -----------------------------------------------------------------------
HOSTNAME="myhost"
interface=eth0
address=
netmask=
gateway=

# -----------------------------------------------------------------------
# DAEMONS
# -----------------------------------------------------------------------
DAEMONS=(syslog-ng @network ntpd crond dbus sshd samba transmissiond)
Я пишу программу сетевой настройки, для этого из rc.conf нужно прочитать параметры: interface=eth0, address=, netmask=, gateway=,
и если нужно, внести изменения: interface=eth0, address=192.168.1.100, netmask=255.255.255.0, gateway=192.168.1.1 .
Делал такое с использованием sed, т.е. regexp'ом.
Вопрос, может в python есть какой нибудь специальный модуль для работы с конфигурационными файлами ??



Офлайн

#2 Окт. 19, 2011 10:47:43

magnet85
От:
Зарегистрирован: 2009-04-13
Сообщения: 91
Репутация: +  2  -
Профиль   Отправить e-mail  

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

Из стандартной библиотеки configparser смотрели? http://docs.python.org/library/configparser.html



Офлайн

#3 Окт. 19, 2011 11:00:49

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

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

Стандартный ConfigParser не может читать ini файлы без секций, для обхода есть такое решение http://stackoverflow.com/questions/2819696/parsing-properties-file-in-python/2819788



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

#4 Окт. 25, 2011 18:11:51

aivs
От:
Зарегистрирован: 2011-05-26
Сообщения: 42
Репутация: +  0  -
Профиль   Отправить e-mail  

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

Пытаюсь обойти секции с помощью предложенного метода, но происходит ошибка.

#!/usr/bin/python
# parse_rc.conf.py
import configparser

class FakeSecHead(object):
def __init__(self, fp):
self.fp = fp
self.sechead = '[asection]\n'
def readline(self):
if self.sechead:
try: return self.sechead
finally: self.sechead = None
else: return self.fp.readline()

config = configparser.SafeConfigParser()
config.readfp(FakeSecHead(open('rc.conf')))
config.items('asection')
Вот ошибка
[aivs@myhost python]$ ./parse_rc.conf.py 
Traceback (most recent call last):
File "./parse_rc.conf.py", line 16, in <module>
config.readfp(FakeSecHead(open('rc.conf')))
File "/usr/lib/python3.2/configparser.py", line 753, in readfp
self.read_file(fp, source=filename)
File "/usr/lib/python3.2/configparser.py", line 708, in read_file
self._read(f, source)
File "/usr/lib/python3.2/configparser.py", line 994, in _read
for lineno, line in enumerate(fp, start=1):
TypeError: 'FakeSecHead' object is not iterable
[aivs@myhost python]$
В чем проблема ??



Офлайн

#5 Окт. 25, 2011 22:46:05

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

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

Проблема в том, что грязный хак, который вам посоветовали был для второго Питона.
Для третьего все проще:

import configparser

parser = configparser.SafeConfigParser()
parser.read_string("[section]\n" + open('rc.conf').read())
print(parser.items('section'))
А для второго нужно сделать тоже самое, что сделали в третьем - читать через StringIO. Кстати, работать такое будет и в третьем.



Отредактировано (Окт. 25, 2011 22:54:25)

Офлайн

#6 Окт. 26, 2011 10:27:59

aivs
От:
Зарегистрирован: 2011-05-26
Сообщения: 42
Репутация: +  0  -
Профиль   Отправить e-mail  

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

Ed спасибо, блин, а я перевод сделал для 2.7!

А возможно ли этим парсером не только читать, но и записывать в конфиг с таким стилем не испортив его, попробовал записать в этот конфиг, вот код

#!/usr/bin/python
# parse_rc.conf.py
import configparser

config = configparser.SafeConfigParser()
config.read_string("[section]\n" + open('rc.conf').read())
config.set('section', 'gateway', '192.168.1.1')
with open('rc.conf', 'w') as configfile:
config.write(configfile)
Получил такой конфиг:
[section]
locale = "ru_RU.UTF-8"
hardwareclock = "localtime"
timezone = "Europe/Moscow"
keymap = "us"
consolefont = ter-u16b
consolemap =
usecolor = "yes"
mod_autoload = "yes"
modules = ()
uselvm = "no"
hostname = "myhost"
interface = eth0
address =
netmask =
gateway = 192.168.1.1
daemons = (syslog-ng @network ntpd crond dbus sshd samba transmissiond)
А мне всего то надо было изменить значение у gateway.



Отредактировано (Окт. 26, 2011 10:56:25)

Офлайн

#7 Окт. 26, 2011 11:30:25

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

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

aivs
А возможно ли этим парсером не только читать, но и записывать в конфиг с таким стилем не испортив его
Если нужно убрать пробелы вокруг = и вывод секции убрать, то возможно, пронаследовав свой парсер от SafeConfigParser и немного исправив метод write. Если я чего-то недосмотрел, то скажите что еще нужно сделать.
Чтобы вам жизнь медом не казалась попробуйте это сделать самостоятельно и показать здесь результат. А я поправлю, если что-то пойдет не так. Вопросы приветствуются.

aivs
А мне всего то надо было изменить значение у gateway.
Кхе-кхе. Не забывайте, что это парсер .ini файлов, а не того, что вы ему подсовываете. И в этом качестве он свою задачу выполняет.
Поэтому у вас 3 пути - либо изгибать существующий парсер под ваши нужды, либо писать свой, либо найти готовый.



Отредактировано (Окт. 26, 2011 11:32:47)

Офлайн

#8 Окт. 26, 2011 12:11:00

aivs
От:
Зарегистрирован: 2011-05-26
Сообщения: 42
Репутация: +  0  -
Профиль   Отправить e-mail  

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

Рассматривая второй вариант, написать свой парсер, т.к. я еще учусь, многих простых вариантов решения не вижу.
Задача:
Изменять значения в конфиге типа:

# Комментарий
Параметр_1 = значение_1
Параметр_2 = значение_2
Мой алгоритм:
1) Считать весь файл с помощью readlines
2) Изменить нужную строку (самое сложное)
3) Записать полученное в файл

По пункту 2 нуждаюсь в помощи. Например мне нужно найти строку начинающуюся с gateway = и изменить ее на gateway = 192.168.1.1, как ?



Офлайн

#9 Окт. 26, 2011 12:39:31

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

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

Я бы попользовал регекспы. Читайте здесь: http://docs.python.org/py3k/library/re.html



Офлайн

#10 Окт. 26, 2011 12:45:05

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

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

Прочитать файл по-строчно.
Разбить строку по ‘=’ на две части - имя и значение.
Засунуть в словарь, используя имя как ключ.
Чтобы теперь прочитать значение то используете my_dict
Запись - проходите по элементам словаря склеиваете ключ + ‘ = ’ + значение, добавляете перевод строки, пишите обратно.

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version