smihael smihael - 1 year ago 112
Ini Question

Reading value from an ini style file with sed/awk

I wrote a simple bash function which would read value from an ini file (defined by variable

) and output it

getConfValue() {
#getConfValue section variable
#return value of a specific variable from given section of a conf file
val=$(sed -nr "/\[$section\]/,/\[/{/$var/p}" $CONF_FILE)
echo "$val"

The problem is that it does not ignore comments and runs into troubles if multiple variables within a section names share common substrings.

Example ini file:

# TEST=old
; TEST=comment
TESTING=this will be output too

getConfValue general PATH
would output
as expected, but running
getConfValue general TEST
shows all the problems this approach has.

How to fix that?

I know there are dedicated tools like
or tools for python, perl and php out in the wild, but I do not want to add extra dependencies for simple config file parsing. A solution incorporating awk instead of sed would be just fine too.

Answer Source

Sticking with sed you could anchor your var search to the start of the record using ^ and end it with an equal sign:


If you are concerned about whitespace in front of your record you could account for that:


That ^(\W|)$var= says "if there is whitespace at the beginning (^(\W) or nothing (|)) before your variable concatenated with an equal sign ($var=)."

If you wanted to switch over to awk you could use something like:

val=$(awk -F"=" -v section=$section -v var=$var '$1=="["section"]"{secFound=1}secFound==1 && $1==var{print $2; secFound=0}' $CONF_FILE)

That awk command splits the record by equal -F"=". Then if the first field in the record is your section ($1=="["section"]") then set variable secFound to 1. Then... if secFound is 1 and the first field is exactly equal to your var variable (secFound==1 && $1==var) then print out the second field ({print $2}) and sets secFound to 0 so we don't pick up any other Test keys.