Linux parse ini file

Создаём парсер для ini-файлов. Теория

ini файлы

Файлы с расширением ini широко распространены не только в мире Windows, но и в других системах (к примеру, php.ini). Формат ini-файла очень прост: файл разделён на секции, в каждой секции может находится произвольное число записей вида «параметр=значение». Имена параметров в разных секциях могут совпадать.
[секция_1]
параметр1=значение1
параметр2=значение2

[секция_2]
параметр1=значение1
параметр2=значение2

Каждый параметр может быть адресован через имя секции и имя параметра: что-нибудь вроде ‘секция_1’.’параметр2′ .

В ini-файлах предусмотрены комментарии — строки начинающиеся с «;».

Строим грамматику

Давайте попробуем описать этот формат виде контекстно свободной грамматики в расширенной нотации Бэкуса-Наура (надеюсь, что будет понятно даже тем, кто не знаком с ней).

Опишем что из себя представляет ini файл. Для этого опишем все конструкции от самых сложных (собственно сам ini-файл) к самым простым (что такое идентификатор). Каждой такой конструкции сопоставляется специальное обозначение (нетерминал), которое определяется через другие нетерминалы и обычные символы (терминалы), которые я буду
задавать в кавычках.

  • Данные ini-файла (inidata) содержат несколько секций (фигурные скобки означают повторение любое количество раз).
    inidata =
    .
  • Секция состоит из названия секции, заключённого в квадратные скобки, за которым со следующей строки идет несколько записей (параметров).
    section = «[«, ident, «]», «\n», .
  • Запись состоит из имени параметра, знака «=», значения параметра и заканчивается концом строки.
    entry = ident, «=», value, «\n» .
  • Определим что такое идентификатор: всё что состоит из букв, цифр или знаков «_. ()<>-#@&*|» (в действительности могут встречаться и другие символы).
    ident = » | «-» | «#» | «@» | «&» |»*» | «|»> .

    Это определение не совсем верно, т.к. идентификатор должен состоять хотя бы из одного символа. Переделаем так:
    ident = identChar, .
    identChar = letter | digit | «_» | «.» | «,» | «:» | «(» | «)» | «<" | ">» | «-» | «#» | «@» | «&» |»*» | «|» .

  • Теперь определим что является значением: всё кроме конца строки (для краткости пришлось расширить нотацию обозначение not)
    value = .

Осталось учесть, что некоторые парсеры/люди любят ставить дополнительные пробелы и пустые строки.
Для этого нам потребуется ввести ещё два нетерминала: пробельные символы используемые в строке и просто пробельные символы.
stringSpaces = <" " | "\t">.
spaces = <" " | "\t" | "\n" | "\r">.

Пробелы могут быть почти где угодно. Поэтому немножко подкорректируем грамматику:
inidata = spaces,

.
section = «[«, ident, «]», stringSpaces, «\n», .
entry = ident, stringSpaces, «=», stringSpaces, value, «\n», spaces .
ident = identChar, .
identChar = letter | digit | «_» | «.» | «,» | «:» | «(» | «)» | «<" | ">» | «-» | «#» | «@» | «&» |»*» | «|» .
value = .
stringSpaces = <" " | "\t">.
spaces = <" " | "\t" | "\n" | "\r">.

Вот в общем-то и всё, что касается грамматики =).

Кто-то, наверное, заметил, что я ничего не сказал про комментарии. Я не забыл — просто их проще «ручками» вырезать =) (в качестве упражнения можете подправить грамматику так, чтобы она комментарии учитывала).

Важно: я немного схитрил и построил грамматику так, чтобы в ней не было левой рекурсии. Обе рассматриваемые мною библиотеки строят рекурсивный нисходящий парсер, который уязвим к левой рекурсии. Перед тем, как использовать эти библиотеки в реальных проектах, убедитесь, что вы понимаете что это такое и как с этим бороться =).

Теперь вы можете сравнить использование этой грамматики для построения парсера на C++ и на Haskell.

PS. Спасибо maxshopen за идею поместить эту статью в блог «Разработка».

Источник

📜 Как парсить файлы конфигурации INI с помощью Bash

Образец INI-файла

Я буду использовать следующий файл конфигурации INI в следующих примерах.

Спарсить весь INI-файл

Прочитаем и проанализируем весь INI-файл.

Вывод будет выглядеть так.

Парсинг одного раздела в INI-файле

Прочитаем и проанализируем отдельный раздел в INI-файле.

Вывод будет выглядеть так.

  • Аудит ИБ (44)
  • Вакансии (10)
  • Закрытие уязвимостей (98)
  • Книги (27)
  • Мануал (1 937)
  • Медиа (66)
  • Мероприятия (38)
  • Мошенники (22)
  • Обзоры (724)
  • Обход запретов (33)
  • Опросы (3)
  • Скрипты (106)
  • Статьи (292)
  • Философия (77)
  • Юмор (17)

Anything in here will be replaced on browsers that support the canvas element

Источник

How can I parse an ini file whose values may contain certain characters?

I have looked at a couple bash ini parsing scripts and I’ve seen this one used a few times here so I’m trying to see if it will work for me. It looks like it reads the ini file line by line multiple times and with each pass it progressively constructs a function that finally gets eval’d. It works fine for some special characters but not others. If a value in the file contains a single quote or greater/less than symbol, the script returns syntax errors. Other symbols create unexpected results as well. How can I handle these characters as the are encountered?

This is the function that parses the ini.

2 Answers 2

The fact that you can do something in bash doesn’t mean that you should.

sh (and bash etc) scripts are best suited to be relatively simple wrappers to launch programs or around text-processing commands. For more complicated tasks, including parsing ini files and acting on them, other languages are more appropriate. Have you considered writing your script in perl or python ? Both have good .ini file parsers — I’ve used perl’s Config::INI module several times when I’ve needed to parse an ini file.

But if you insist on doing it in bash, you should use an associative array instead of setting individual variables.

Start with something like this:

The sed script deletes the [Section1] line (actually, all lines beginning with an open-square-bracket [ — you will want to handle this differently [1] in an ini file with multiple sections), and removes comments as well as leading and trailing blanks. The while loop reads in each line, using = as a field delimiter, and assigns the contents to variables $key and $val, which are then added to the $config array.

You can use the array entries later in your script like this:

[1] awk or perl have conveniently easy ways of reading files in «paragraph» mode. A paragraph being defined as a block of text separated from other text blocks by one or more blank lines.

e.g. to work with only [Section1] , insert the awk script below immediately before the sed script feeding into the while loop above:

(and remove «$inifile» from the end of the sed command line, of course — you don’t want to feed the file in again after you’ve gone to the trouble of extracting only [Section1] from it).

Setting ORS isn’t strictly necessary if you’re only extracting one section from the ini file — but will be useful to maintain paragraph separation if you’re extracting two or more sections.

Источник

Use an INI file in C on Linux

Is there a standard way of reading a kind of configuration like INI files for Linux using C?

I am working on a Linux based handheld and writing code in C.

Otherwise, I shall like to know about any alternatives.

Final update:

I have explored and even used LibConfig. But the footprint is high and my usage is too simple. So, to reduce the footprint, I have rolled out my own implementation. The implementation is not too generic, in fact quite coupled as of now. The configuration file is parsed once at the time of starting the application and set to some global variables.

7 Answers 7

a simple library for processing structured configuration files, like this one: test.cfg. This file format is more compact and more readable than XML. And unlike XML, it is type-aware, so it is not necessary to do string parsing in application code.

Libconfig is very compact — a fraction of the size of the expat XML parser library. This makes it well-suited for memory-constrained systems like handheld devices.

The library includes bindings for both the C and C++ languages. It works on POSIX-compliant UNIX and UNIX-like systems (GNU/Linux, Mac OS X, Solaris, FreeBSD), Android, and Windows (2000, XP and later).

Источник

Чем парсить конфигурационные файлы?

Есть программа, которой нужен конфиг. Иногда надо записать что-нибудь туда же. Чем лучше развернуть такое? Подойдёт любой xml, json или е.ч.
P.s. не в development так как не сильно то и специфичный вопрос. От пользователей спрошу какую библиотеку для парсинга чаще всего встречаете?
P.p.s. пишу на C.

Бери JSON и не заморачивайся.
Только обрати внимание, чтобы парсер поддерживал комментарии. Некоторые либо вообще их не поддерживают, либо нужно включить специальную опцию.

libxml2 Но смотря какой жирности будут конфиги – может и чересчур. Стандартного key:value/\n не хватает?

Я могу только на gambas дать свой простой парсер.

что скажешь про tinyxml?

хранить конфиги в xml — зло

Хм, попробуй, я не пользовался, но судя по libhunt-compare он живет и развивается, что не может не радовать.

Да XML больше всего понравился PugiXML. Но во-первых, это плюсы, а во-вторых, конфиги в XML — это садизм.

Если конфиги человекоредактируемые — «любой xml, json» ни в коем случае не брать. Если не хватает ini-формата, посмотри на yaml лучше или lua.

Хочешь наказать своих пользователей — бери хмл.

Хочешь быть в их глазах няшей — используй JSON.

Оба варианта достаточно просты с т.з. разрабатывать, но хмл это ад для того, кто его вручную редактирует

Редактировать будут вручную, значит json? Какую библиотеку посоветуешь? Чтобы освоиться быстро и была искаропки в репах слаки.

хмл это ад для того, кто его вручную редактирует

если для ручного редактирования в режиме обычного текста то строковый типа ini или quake config (в геймдеве вроде сейчас популярен lua script), ни в коем случае не xml или json.
xml создан для графического отображения, а json для внутрипрограмного использования, использование обоих для текстовых конфигураций есть неправильно.

Поддерживаю. ini самый удобный и читаемый формат. А в случае, когда сложно, Lua для конфигов может выглядеть очень опрятно и читаемо.

xml создан для графического отображения

Именно. А популярность набрал потому что роботам нравится и потому что стримовый.

Человеку читать его ещё можно, но писать это боль.

Чем парсить ini?

Хрен его знает, вытащи парсер из libass

iniparser только знаю, да норм. Спс

А ну ок если нашел.
В АSS просто синтаксис более приятный

А с json-то в чём проблема, кстати?

конфиги и ведроидоюай это разные вещи, как ведроидокодер говорю.

С ним нет проблем, просто он создан для использования внутри программ, а не для редактирования руками.

как другой ведроидокодер говорю, что при должном умении и старании можно устроить вполне хороший ад:)

какой именно конфиг? Там только ключ-значение, или есть сложные структуры?

Хочешь их наказать ещё больше — используй JSON.

FFGJ — в json нет комметнариев, а это для конфига очень и очень важно.

Не советую json. Xml тоже только если нет других вариантов. Луче стандартный ini или config файл, как в линуксе в /etc/. Пользователи будут путаться с json, делать ошибки. xml не так страшен, но тоже будут путаться. Проще всего key=value, и все. И лучше два config-файла, а не один. Один тот, в который пишут пользователи, другой тот, в который пишет программа.

Источник

Читайте также:  Обновление windows kb2999226 x64
Оцените статью