Как получить значение INI в сценарии оболочки? - PullRequest
80 голосов
/ 12 июня 2011

У меня есть файл parameters.ini, например:

[parameters.ini]
    database_user    = user
    database_version = 20110611142248

Я хочу прочитать и использовать версию базы данных, указанную в файле parameters.ini, из скрипта оболочки bash, чтобы я мог обработатьЭто.

#!/bin/sh    
# Need to get database version from parameters.ini file to use in script    
php app/console doctrine:migrations:migrate $DATABASE_VERSION

Как бы я это сделал?

Ответы [ 24 ]

71 голосов
/ 12 июня 2011

Как насчет поиска этой строки с использованием awk

version=$(awk -F "=" '/database_version/ {print $2}' parameters.ini)
34 голосов
/ 01 марта 2015

Вы можете использовать собственный синтаксический анализатор bash для интерпретации значений ini:

$ source <(grep = file.ini)

Пример файла:

[section-a]
  var1=value1
  var2=value2
  IPS=( "1.2.3.4" "1.2.3.5" )

Для доступа к переменным вы просто печатаете их: echo $var1.Вы также можете использовать массивы, как показано выше (echo ${IPS[@]}).

Если вам нужно только одно значение, просто введите grep:

source <(grep var1 file.ini)

Это просто, так как вам не нужнодля любой внешней библиотеки для анализа данных, но это имеет некоторые недостатки.Например:

  • Если у вас есть пробелы между = (имя и значение переменной), то сначала вы должны обрезать пробелы, например,

    $ source <(grep = file.ini | sed 's/ *= */=/g')
    

    Или, если вам не нужны пробелы (в том числе посередине), используйте:

    $ source <(grep = file.ini | tr -d ' ')
    
  • Для поддержки ; комментариев замените их на #:

    $ sed "s/;/#/g" foo.ini | source /dev/stdin
    
  • Разделы не поддерживаются (например, если у вас [section-name], вы должны отфильтровать его, как показано выше, например, grep =), то же самое длядругие непредвиденные ошибки.

    Если вам нужно прочитать определенное значение в определенном разделе, используйте grep -A, sed, awk или ex).

    Например

    source <(grep = <(grep -A5 '\[section-b\]' file.ini))
    

    Примечание: где -A5 - количество строк, которые нужно прочитать в разделе.Замените source на cat для отладки.

  • Если у вас есть какие-либо ошибки синтаксического анализа, игнорируйте их, добавив: 2>/dev/null

См. Также: Как проанализировать и преобразовать INI-файл в переменные массива bash? при ошибке сервера SE

27 голосов
/ 12 июня 2011

Bash не предоставляет анализатор для этих файлов. Очевидно, что вы можете использовать команду awk или пару вызовов sed, но если вы bash-priest и не хотите использовать какую-либо другую оболочку, вы можете попробовать следующий неясный код:

#!/usr/bin/env bash
cfg_parser ()
{
    ini="$(<$1)"                # read the file
    ini="${ini//[/\[}"          # escape [
    ini="${ini//]/\]}"          # escape ]
    IFS=$'\n' && ini=( ${ini} ) # convert to line-array
    ini=( ${ini[*]//;*/} )      # remove comments with ;
    ini=( ${ini[*]/\    =/=} )  # remove tabs before =
    ini=( ${ini[*]/=\   /=} )   # remove tabs after =
    ini=( ${ini[*]/\ =\ /=} )   # remove anything with a space around =
    ini=( ${ini[*]/#\\[/\}$'\n'cfg.section.} ) # set section prefix
    ini=( ${ini[*]/%\\]/ \(} )    # convert text2function (1)
    ini=( ${ini[*]/=/=\( } )    # convert item to array
    ini=( ${ini[*]/%/ \)} )     # close array parenthesis
    ini=( ${ini[*]/%\\ \)/ \\} ) # the multiline trick
    ini=( ${ini[*]/%\( \)/\(\) \{} ) # convert text2function (2)
    ini=( ${ini[*]/%\} \)/\}} ) # remove extra parenthesis
    ini[0]="" # remove first element
    ini[${#ini[*]} + 1]='}'    # add the last brace
    eval "$(echo "${ini[*]}")" # eval the result
}

cfg_writer ()
{
    IFS=' '$'\n'
    fun="$(declare -F)"
    fun="${fun//declare -f/}"
    for f in $fun; do
        [ "${f#cfg.section}" == "${f}" ] && continue
        item="$(declare -f ${f})"
        item="${item##*\{}"
        item="${item%\}}"
        item="${item//=*;/}"
        vars="${item//=*/}"
        eval $f
        echo "[${f#cfg.section.}]"
        for var in $vars; do
            echo $var=\"${!var}\"
        done
    done
}

Использование:

# parse the config file called 'myfile.ini', with the following
# contents::
#   [sec2]
#   var2='something'
cfg.parser 'myfile.ini'

# enable section called 'sec2' (in the file [sec2]) for reading
cfg.section.sec2

# read the content of the variable called 'var2' (in the file
# var2=XXX). If your var2 is an array, then you can use
# ${var[index]}
echo "$var2"

Bash ini-parser можно найти на сайте блога Old School DevOps .

18 голосов
/ 08 мая 2015

Просто включите файл .ini в тело bash:

Файл example.ini :

DBNAME=test
DBUSER=scott
DBPASSWORD=tiger

Файл example.sh

#!/bin/bash
#Including .ini file
. example.ini
#Test
echo "${DBNAME}   ${DBUSER}  ${DBPASSWORD}"
16 голосов
/ 24 ноября 2016

Sed однострочник, который принимает во внимание разделы.Файл примера:

[section1]
param1=123
param2=345
param3=678

[section2]
param1=abc
param2=def
param3=ghi

[section3]
param1=000
param2=111
param3=222

Скажем, вы хотите param2 из раздела 2.Запустите следующее:

sed -nr "/^\[section2\]/ { :l /^param2[ ]*=/ { s/.*=[ ]*//; p; q;}; n; b l;}" ./file.ini

даст вам

def
11 голосов
/ 25 января 2013

Все решения, которые я видел до сих пор, также попадают в закомментированные строки.Этот не сделал, если код комментария ;:

awk -F '=' '{if (! ($0 ~ /^;/) && $0 ~ /database_version/) print $2}' file.ini
11 голосов
/ 12 июня 2011

одно из возможных решений

dbver=$(sed -n 's/.*database_version *= *\([^ ]*.*\)/\1/p' < parameters.ini)
echo $dbver
8 голосов
/ 14 сентября 2014

Отображение значения my_key в ini-стиле my_file :

sed -n -e 's/^\s*my_key\s*=\s*//p' my_file
  • -n - по умолчанию ничего не печатать
  • -e - выполнить выражение
  • s/PATTERN//p - отобразить все, что следует этому шаблону В шаблоне:
  • ^ - шаблон начинается с началалинии
  • \s - символ пробела
  • * - ноль или много символов (пробел)

Пример:

$ cat my_file
# Example INI file
something   = foo
my_key      = bar
not_my_key  = baz
my_key_2    = bing

$ sed -n -e 's/^\s*my_key\s*=\s*//p' my_file
bar

Итак:

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

4 голосов
/ 15 сентября 2014

Для людей (таких как я), желающих читать INI-файлы из сценариев оболочки (чтение оболочки, а не bash) - я запустил небольшую вспомогательную библиотеку, которая пытается сделать именно это:

https://github.com/wallyhall/shini (лицензия MIT, делайте с ней, как вам угодно. Я ссылался выше, в том числе встроенный, поскольку код довольно длинный.)

Это несколько более "сложно", чем простые строки sedпредложено выше - но работает очень схожим образом.

Функция читает строку в строку построчно - ищет маркеры разделов ([section]) и объявления ключа / значения (key=value).

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

3 голосов
/ 26 августа 2014

Вы можете использовать инструмент crudini для получения значений ini, например:

DATABASE_VERSION=$(crudini --get parameters.ini '' database_version)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...