How do I grab an INI value within a shell script?

I have a parameters.ini file, such as:

[parameters.ini]
    database_user    = user
    database_version = 20110611142248

I want to read in and use the database version specified in the parameters.ini file from within a bash shell script so I can process it.

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

How would I do this?


Solution 1:

How about grepping for that line then using awk

version=$(awk -F "=" '/database_version/ {print $2}' parameters.ini)

Solution 2:

You can use bash native parser to interpret ini values, by:

$ source <(grep = file.ini)

Sample file:

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

To access variables, you simply printing them: echo $var1. You may also use arrays as shown above (echo ${IPS[@]}).

If you only want a single value just grep for it:

source <(grep var1 file.ini)

For the demo, check this recording at asciinema.

It is simple as you don't need for any external library to parse the data, but it comes with some disadvantages. For example:

  • If you have spaces between = (variable name and value), then you've to trim the spaces first, e.g.

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

    Or if you don't care about the spaces (including in the middle), use:

      $ source <(grep = file.ini | tr -d ' ')
    
  • To support ; comments, replace them with #:

      $ sed "s/;/#/g" foo.ini | source /dev/stdin
    
  • The sections aren't supported (e.g. if you've [section-name], then you've to filter it out as shown above, e.g. grep =), the same for other unexpected errors.

    If you need to read specific value under specific section, use grep -A, sed, awk or ex).

    E.g.

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

    Note: Where -A5 is the number of rows to read in the section. Replace source with cat to debug.

  • If you've got any parsing errors, ignore them by adding: 2>/dev/null

See also:

  • How to parse and convert ini file into bash array variables? at serverfault SE
  • Are there any tools for modifying INI style files from shell script

Solution 3:

Sed one-liner, that takes sections into account. Example file:

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

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

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

Say you want param2 from section2. Run the following:

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

will give you

def