I need to retrieve the value of a key from an ini file with typical structure:
[abcd]
key1=a
key2=b
[efgh]
key1=c
key2=d
[hijk]
key1=e
key2=f
with key names repeated in different sections, and no consistant naming/order of sections. How could I find key1 from efgh? If I grep then I'll find all key1's (and I don't know the order of the sections).
I suspect sed or awk can do this but I can't find it...
This could be a start:
awk -F'=' -v section="[efgh]" -v k="key1" '
$0==section{ f=1; next } # Enable a flag when the line is like your section
/\[/{ f=0; next } # For any lines with [ disable the flag
f && $1==k{ print $0 } # If flag is set and first field is the key print key=value
' ini.file
You pass two variables, section
and k
. section
needs to contain the section you want to look under. k
should contain the key
you are trying to obtain value for.
Find value of key1
under section [efgh]
:
$ awk -F'=' -v section="[efgh]" -v k="key1" '
$0==section{ f=1; next }
/\[/{ f=0; next }
f && $1==k{ print $0 }
' ini.file
key1=c
Find value of key2
under section [hijk]
:
$ awk -F'=' -v section="[hijk]" -v k="key2" '
$0==section{ f=1; next }
/\[/{ f=0; next }
f && $1==k{ print $0 }
' ini.file
key2=f
Using sed
sed -r ':a;$!{N;ba};s/.*\[efgh\][^[]*(key1=[^\n]*).*/\1/' file
key1=c
another way
sed -nr '/\[efgh\]/,/\[/{/key1/p}' file
One way:
sed -n '/\[efgh\]/,/\[.*\]/p' file | awk -F= '/key2/{print $2}'
Using sed, extract the range of lines from [efgh] to the next [....] pattern. Using awk, search for key2 in this range of lines and get the value.
These sed
one-liners worked for me, shamelessly copied from github:thomedes/ini.sed
# List all [sections] of a .INI file
sed -n 's/^[ \t]*\[\(.*\)\].*/\1/p'
# Read KEY from [SECTION]
sed -n '/^[ \t]*\[SECTION\]/,/\[/s/^[ \t]*KEY[ \t]*=[ \t]*//p'
# Read all values from SECTION in a clean KEY=VALUE form
sed -n '/^[ \t]*\[SECTION\]/,/\[/s/^[ \t]*\([^#; \t][^ \t=]*\).*=[ \t]*\(.*\)/\1=\2/p'
# examples:
sed -n 's/^[ \t]*\[\(.*\)\].*/\1/p' /etc/samba/smb.conf
sed -n '/^[ \t]*\[global\]/,/\[/s/^[ \t]*workgroup[ \t]*=[ \t]*//p' /etc/samba/smb.conf
sed -n '/^[ \t]*\[global\]/,/\[/s/^[ \t]*\([^#; \t][^ \t=]*\).*=[ \t]*\(.*\)/\1=\2/p' /etc/samba/smb.conf
This might work for you (GNU sed):
sed -rn '/^\[/{h;d};G;s/^key1=(.*)\n\[efgh\]$/\1/p' file
Copy the section header and compare it against the section body.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With