Skip to content

Instantly share code, notes, and snippets.

@gorenje
Last active July 19, 2020 17:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gorenje/0125c2e6240102b5509161ca22a69483 to your computer and use it in GitHub Desktop.
Save gorenje/0125c2e6240102b5509161ca22a69483 to your computer and use it in GitHub Desktop.
This is the same as https://blog.sleeplessbeastie.eu/2019/11/11/how-to-parse-ini-configuration-file-using-bash/ except
that it also handles section names with minus ('-').
[main]
description = Sample configuration
timeout = 10
monitoring_interval = 20
[database-fubar]
server = db.example.org
port = 3306
username = dbuser
password = dbpass
[monitor-another-minus]
servers[] = www.example.org
servers[] = proxy.example.org
servers[] = cache.example.org
servers[] = bastion.example.org
prompt> ./parse.sh example.ini
Configuration description: Sample configuration
[database-fubar]
port = 3306 (access it using ${configuration_database_fubar[port]})
password = dbpass (access it using ${configuration_database_fubar[password]})
server = db.example.org (access it using ${configuration_database_fubar[server]})
username = dbuser (access it using ${configuration_database_fubar[username]})
[monitor-another-minus]
servers = www.example.org proxy.example.org cache.example.org bastion.example.org (access it using ${configuration_monitor_another_minus[servers]})
[main]
timeout = 10 (access it using ${configuration_main[timeout]})
description = Sample configuration (access it using ${configuration_main[description]})
monitoring_interval = 20 (access it using ${configuration_main[monitoring_interval]})
#!/bin/bash
# Read and parse simple INI file
# Get INI section
ReadINISections(){
local filename="$1"
gawk '{ if ($1 ~ /^\[/) section=tolower(gensub(/\[(.+)\]/,"\\1",1,$1)); configuration[section]=1 } END {for (key in configuration) { print key} }' ${filename}
}
# Get/Set all INI sections
GetINISections(){
local filename="$1"
sections="$(ReadINISections $filename)"
for section in $sections; do
array_name="configuration_${section//-/_}"
declare -g -A ${array_name}
done
eval $(gawk -F= '{
if ($1 ~ /^\[/)
section=tolower(gensub(/\[(.+)\]/,"\\1",1,$1))
else if ($1 !~ /^$/ && $1 !~ /^;/) {
gsub(/^[ \t]+|[ \t]+$/, "", $1);
gsub(/[\[\]]/, "", $1);
gsub(/^[ \t]+|[ \t]+$/, "", $2);
if (configuration[section][$1] == "")
configuration[section][$1]=$2
else
configuration[section][$1]=configuration[section][$1]" "$2}
}
END {
for (section in configuration)
for (key in configuration[section]) {
section_name = section
gsub( "-", "_", section_name)
print "configuration_" section_name "[\""key"\"]=\""configuration[section][key]"\";"
}
}' ${filename}
)
}
if [ "$#" -eq "1" ] && [ -f "$1" ]; then
filename="$1"
GetINISections "$filename"
echo -n "Configuration description: "
if [ -n "${configuration_main["description"]}" ]; then
echo "${configuration_main["description"]}"
else
echo "missing"
fi
echo
for section in $(ReadINISections "${filename}"); do
echo "[${section}]"
for key in $(eval echo $\{'!'configuration_${section//-/_}[@]\}); do
echo -e " ${key} = $(eval echo $\{configuration_${section//-/_}[$key]\}) (access it using $(echo $\{configuration_${section//-/_}[$key]\}))"
done
done
else
echo "missing INI file"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment