Reverse search ini section

93 Views Asked by At

Assume this .ini file.

[section_x]
my_value=abc
another_value=def

[section_2]
my_value=stv
another_value=xyz

[this_one]
my_value=something
another_value=sure

Assume the system has the value something loaded in it's environment variable.
Using bash, how can I search the .ini file to match the value, and then load that section, in this case this_one? Based on the section, it then loads another_value.

In this case, the outcome would be sure.

Another example for clarity: if the system had stv loaded in it's env, the outcome is xyz.

4

There are 4 best solutions below

4
steffen On

As long as $variable doesn't contain anything special, you can use awk in "paragraph mode":

$ awk -v RS= "/my_value=$variable/" file | grep -Po '(?<=another_value=).*'
sure

Alternatively, in case grep doesn't support -P or negative lookbehinds:

$ awk -v RS= "/my_value=$variable/" file | sed '/another_value/!d;s/.*=//'
sure
6
Paolo On

Using awk:

$ v="something"
$ awk -F= -v value="$v" '$1 ~ "my_value" && $2 ~ value {getline; print $2}' file
sure
0
tshiono On

Assuming the another_value line does not appear before the my_value line, how about a sed solution:

export variable="something"
sed -n "/my_value=$variable/,/^$/p" file | sed "/another_value/!d;s/.*=//"
0
David C. Rankin On

Another awk one-liner that finds "something" and then returns the next value for another_value can be:

awk -F= -v ev="something" 'av && $1=="another_value" {print $2; exit} $2==ev {av=1}' file

Where av is just a flag variable for another_value which is set nonzero when the entry with something as its value is reached leading to the next another_value to be captured and output.

The benefit here is you have a single call to awk instead of calls to multiple utilities.

Example Use/Output

With your example input in dat/some.ini, you would have:

$ awk -F= -v ev="something" 'av && $1=="another_value" {print $2; exit} $2==ev {av=1}' dat/some.ini
sure

Or if you wanted to find any of the other values, just change what you provide as the variable ev, e.g.

awk -F= -v ev="abc" 'av && $1=="another_value" {print $2; exit} $2==ev {av=1}' dat/some.ini
def

and

$ awk -F= -v ev="stv" 'av && $1=="another_value" {print $2; exit} $2==ev {av=1}' dat/some.ini
xyz