Я пытаюсь преобразовать INI-файл в переменные массива Bash. Пример INI, как показано ниже:
[foobar]
session=foo
path=/some/path
[barfoo]
session=bar
path=/some/path
так они становятся:
session[foobar]=foo
path[foobar]=/some/path
session[barfoo]=bar
и так далее.
Прямо сейчас я мог придумать только эту команду
awk -F'=' '{ if ($1 ~ /^\[/) section=$1; else if ($1 !~ /^$/) print $1 section "=" $2 }'
Кроме того, другая проблема заключается в том, что он не учитывает пробелы =
. Я думаю, что sed
, вероятно, лучше подходит для этой работы, но я не знаю, как хранить и хранить временную переменную для имени раздела в sed
.
Так есть идеи, как это сделать?
ini
парсер вbash
.Ответы:
Gawk принимает регулярные выражения в качестве разделителей полей. Следующее исключает пробелы вокруг знака равенства, но сохраняет их в остальной части строки. Кавычки добавляются вокруг значения, поэтому эти пробелы, если они есть, сохраняются при выполнении присваивания Bash. Я предполагаю, что имена разделов будут числовыми переменными, но если вы используете Bash 4, было бы легко адаптировать это для использования ассоциативных массивов с именами разделов в качестве индексов.
Обратите внимание, что вы можете также захотеть удалить пробел, который показывает Халед (только на $ 1 и разделе), так как имена переменных Bash не могут содержать пробелы.
Кроме того, этот метод не будет работать, если значения содержат знаки равенства.
Другим методом будет использование
while read
цикла Bash и выполнение назначений при чтении файла, использованиеdeclare
которого защищено от большинства вредоносного содержимого.Опять же, ассоциативные массивы можно довольно легко поддерживать.
источник
Я бы использовал простой скрипт на python для этой работы, так как он имеет встроенный парсер INI :
а затем в bash:
Конечно, в awk есть более короткие реализации, но я думаю, что это более читабельно и проще в обслуживании.
источник
print "declare -A %s" % (sec)
eval
:source <(cat in.ini | ./ini2arr.py)
Если вы хотите устранить лишние пробелы, вы можете использовать встроенную функцию
gsub
. Например, вы можете добавить:Это удалит все пробелы. Если вы хотите удалить пробелы в начале или конце токена, вы можете использовать
источник
Вот чистое решение Bash.
Это новая и улучшенная версия того, что отправил chilladx:
https://github.com/albfan/bash-ini-parser
Для действительно простого начального примера: после того, как вы загрузите его, просто скопируйте файлы
bash-ini-parser
иscripts/file.ini
в тот же каталог, затем создайте сценарий тестирования клиента, используя пример, который я привел ниже, для этого же каталога.Вот некоторые дополнительные улучшения, которые я сделал в скрипте bash-ini-parser ...
Если вы хотите иметь возможность читать ini-файлы с окончаниями строк Windows, а также с Unix, добавьте эту строку в функцию cfg_parser, следующую сразу за той, которая читает файл:
Если вы хотите читать файлы с ограниченными правами доступа, добавьте эту необязательную функцию:
источник
chmod 777
. Хотя в лучшем случае это ненадежная практика, нет необходимости делать исполняемый файл INI. Лучшим подходом будет использоватьsudo
чтение файла, а не связываться с разрешениями.Всегда предполагая наличие ConfigParser в Python, можно создать вспомогательную функцию оболочки следующим образом:
$IFACE
и$param
являются соответственно разделом параметра.Затем этот помощник разрешает такие звонки:
Надеюсь это поможет!
источник
Если у вас есть доступный Git и вы согласны с ограничением невозможности использовать подчеркивания в именах ключей, вы можете использовать его
git config
как синтаксический анализатор / редактор INI общего назначения.Он будет обрабатывать разбор пары ключ / значение по всему
=
и отбрасывать незначительные пробелы, плюс вы получите комментарии (как;
и#
), так и приведение типов в основном бесплатно. Я включил полный рабочий пример для ввода ОП.ini
и желаемого вывода (ассоциативные массивы Bash) ниже.Тем не менее, учитывая конфигурационный файл, как это
… Если вам просто нужно быстрое и грязное решение, и вы не женаты на идее иметь настройки в ассоциативном массиве Bash, вы можете получить всего лишь:
который создает переменные среды с именами
sectionname_variablename
в текущей среде. Это, конечно, работает, только если вы можете верить, что ни одно из ваших значений никогда не будет содержать точку или пробел (более подробное решение см. Ниже).Другие простые примеры
Извлечение произвольных значений с использованием функции оболочки для сохранения ввода:
Псевдоним тоже будет в порядке, но он обычно не раскрывается в сценарии оболочки [ 1 ], и в любом случае псевдонимы заменяются функциями оболочки «почти для всех целей» [ 2 ], согласно странице руководства Bash .
С помощью этой
--type
опции вы можете «канонизировать» определенные настройки в виде целых чисел, логических значений или путей (автоматически расширяется~
):Чуть более надежный, быстрый и грязный пример
Сделайте все переменные
mytool.ini
доступными какSECTIONNAME_VARIABLENAME
в текущей среде, сохранив внутренний пробел в значениях ключа:То, что делает выражение sed, на английском языке, это
\1
, затем\2
, и\3
Последовательности
\U
и\E
в строке замены (верхний регистр этой части строки замены) являютсяsed
расширением GNU . В macOS и BSD вы бы просто использовали несколько-e
выражений для достижения одного и того же эффекта.Работа со встроенными кавычками и пробелами в названиях разделов (что
git config
позволяет) оставляется в качестве упражнения для читателя.:)
Использование имен разделов в качестве ключей в ассоциативном массиве Bash
Данный:
Это даст результат, который запрашивает OP, просто переставив некоторые записи в выражении замены sed, и будет работать без GNU sed:
Я предполагаю, что при цитировании реального
.ini
файла могут возникнуть некоторые проблемы , но это работает для приведенного примера. Результат:источник