Last active
July 27, 2023 22:45
-
-
Save ernstki/5147c5e616b612d0cbf2618343b7dc21 to your computer and use it in GitHub Desktop.
parse a Windows-style .ini file into a Bash associative array declaration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/sed -nf | |
## | |
## parse a Windows-style .ini file into key-value pairs that can be 'eval'd | |
## into a Bash associative array declaration | |
## | |
## Usage: | |
## $ eval "declare -A cfg=( $(ini2assoc config.ini) )" | |
## $ echo "section.keyname = ${cfg[section.keyname]}" | |
## | |
## Input: | |
## A Windows-style .ini file with unquoted, single-line values; '#' and | |
## ';' are supported as comment characters and blank lines are ignored | |
## | |
## Returns: | |
## Bash associative array syntax of the form: [section.keyname]="value" | |
## | |
## Notes: | |
## - no special care is taken to escape quote characters within values, | |
## which could result in a Bash syntax error | |
## - this script does only incidental input sanitization (stripping | |
## anything after a semicolon); use only with .ini files you wrote and | |
## have protected from unintentional modification | |
## | |
## Author: | |
## Dr. Michaël Grünewald (https://github.com/michipili) | |
## with modifications by Kevin Ernst (ernstki -at- mail.uc.edu) | |
## | |
## Source(s): | |
## https://gist.github.com/ernstki/5147c5e616b612d0cbf2618343b7dc21 | |
## https://michipili.github.io/shell/2015/06/05/shell-configuration-file.html | |
## | |
## TODOs (exercises left for the reader): | |
## - support interpolation of previously-defined keys, e.g. '${keyname}' | |
## - recognize "\" as line continuation character | |
## - properly escape quote characters within values | |
## - try harder to sanitize untrusted input, so it can be safely 'eval'd | |
## | |
# key-value pairs outside any section are assigned to 'default' section | |
1 { | |
x | |
s/^/[default./ | |
x | |
} | |
# ignore comments and blank lines; trim trailing comments | |
/^[;#]/d | |
/^[[:space:]]*$/d | |
s/[[:space:]]*[;#].*$// | |
# format keys so they can be fetched from the resulting associative array like | |
# this: ${cfg[section.keyname]} -> value | |
# first, store section name as '[section.'; later we'll add 'keyname]=' | |
/^\[/ { | |
s/\[\(.*\)\]/[\1./ | |
x | |
b | |
} | |
# now, for key=value lines, trim leading whitespace, add 'keyname]=' to make | |
# this a valid key for Bash associative arrays, then prepend the section name | |
# from the hold buffer | |
/=/ { | |
s/^[[:space:]]*// | |
s/[[:space:]]*=[[:space:]]*/]="/ | |
G | |
s/\(.*\)\n\(.*\)/\2\1"/ | |
p | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment