diff --git a/README b/README index 9f6c569..ccae2cc 100644 --- a/README +++ b/README @@ -8,20 +8,20 @@ The INI file format supports the following features: Sections: [section] Properties: name=value -Comments: ; comment +Comments: ; comment # comment -Blank lines and trailing writespace are ignored as is whitespace around -the '=' - ie. +Blank lines and trailing writespace are ignored as is whitespace around +the '=' - ie. name = value -is equivalent to +is equivalent to name=value -Whitespace and quotes within a value are preserved (though values don't -in general need to be quoted and will not be subject to shell parameter +Whitespace and quotes within a value are preserved (though values don't +in general need to be quoted and will not be subject to shell parameter splitting) Values can be continuted onto subsequent lines if these are prefixed with @@ -30,7 +30,7 @@ whitespace - ie. name=line1 line2 -is equivalent to: +is equivalent to: name = line1 line2 @@ -39,7 +39,7 @@ keys in the format "
." (properties without an associated section are stored as ".". In most cases this is transparent as the list/get commands can be used to query the data -The functionality is more or less equivalent to the Python ConfigParser +The functionality is more or less equivalent to the Python ConfigParser module with the following exceptions - Properties are allowed outside sections @@ -70,6 +70,10 @@ section1.abc section1.ghi section2.xyz +$ listKeys section1 +section1.abc +section1.ghi + $ listAll .global a global value section1.abc def @@ -80,6 +84,10 @@ $ listSection section1 section1.abc def section1.ghi jkl +$listSection +section1 +section2 + $ getProperty global a global value @@ -99,7 +107,7 @@ parseIniFile < file Parse ini file (reads from stdin) and saves data to global _CONFIG var -listKeys +listKeys List keys present in config file in format "
." @@ -107,14 +115,14 @@ listAll List keys and data in format "
. " -listSection
+listSection List keys and data for given section (sepcified as $1) in format - " " + " ",if will list all sections when section parameter empty getProperty [name|section.name] - Print value for given property (sepcified as $1) + Print value for given property (sepcified as $1) Properties without a section can be queried directly as "name" (rather than ".name") @@ -122,11 +130,9 @@ getProperty [name|section.name] getPropertyVar [name|section.name] - Save value for given property (sepcified as $2) + Save value for given property (sepcified as $2) into shell variable (specified as $1) Properties without a section can be queried directly as "name" (rather than ".name") Returns 0 (true) if property found otherwise 1 (false) - - diff --git a/ini_parser.sh b/ini_parser.sh index b336d9f..0e376a4 100755 --- a/ini_parser.sh +++ b/ini_parser.sh @@ -4,25 +4,25 @@ # ------------ # # Functions for parsing INI-style file natively in bash. -# +# # The INI file format supports the following features: # # Sections: [section] # Properties: name=value -# Comments: ; comment +# Comments: ; comment # # comment # -# Blank lines and trailing writespace are ignored as is whitespace around -# the '=' - ie. -# +# Blank lines and trailing writespace are ignored as is whitespace around +# the '=' - ie. +# # name = value -# -# is equivalent to -# +# +# is equivalent to +# # name=value # -# Whitespace and quotes within a value are preserved (though values don't -# in general need to be quoted and will not be subject to shell parameter +# Whitespace and quotes within a value are preserved (though values don't +# in general need to be quoted and will not be subject to shell parameter # splitting) # # Values can be continuted onto subsequent lines if these are prefixed with @@ -31,8 +31,8 @@ # name=line1 # line2 # -# is equivalent to: -# +# is equivalent to: +# # name = line1 line2 # # Properties are stored in the global _CONFIG array as ( k1 v1 k2 v2 ... ) with @@ -40,9 +40,9 @@ # section are stored as ".". In most cases this is transparent as the # list/get commands can be used to query the data # -# The functionality is more or less equivalent to the Python ConfigParser +# The functionality is more or less equivalent to the Python ConfigParser # module with the following exceptions -# +# # - Properties are allowed outside sections # - Multi-line properties are joined with ' ' rather than '\n' (due to shell # quoting issues) @@ -51,7 +51,7 @@ # ----- # # Given the following ini file (test.ini) - -# +# # ; A test ini file # global = a global value # [section1] @@ -60,7 +60,7 @@ # [section2] # xyz = abc ; extends over two lines # def -# +# # Parse config file - # # $ parseIniFile < test/t2.ini @@ -71,12 +71,20 @@ # section1.ghi # section2.xyz # +# $ listKeys section1 +# section1.abc +# section1.ghi +# # $ listAll # .global a global value # section1.abc def # section1.ghi jkl # section2.xyz abc def # +# $ listSection +# section1 +# section2 +# # $ listSection section1 # section1.abc def # section1.ghi jkl @@ -97,6 +105,7 @@ shopt -s extglob _CONFIG=() +_SECTION=() # Commands # -------- @@ -115,7 +124,7 @@ function parseIniFile() { local IFS="" - while read LINE + while read LINE do LINE=${LINE%%[;#]*} # Strip comments LINE=${LINE%%*( )} # Strip trailing whitespace @@ -134,9 +143,10 @@ function parseIniFile() { if [[ $LINE =~ ^\[([[:alnum:]]+)\] ]] # Section then SECTION=${BASH_REMATCH[1]} + _SECTION=(${_SECTION[@]} "${SECTION}") KEY="" elif [[ $LINE =~ ^([^[:space:]]+)[[:space:]]*=[[:space:]]*(.+) ]] # Property - then + then KEY=${BASH_REMATCH[1]} VALUE="${BASH_REMATCH[2]}" fi @@ -156,9 +166,13 @@ function parseIniFile() { function listKeys() { local -i i + local SECTION=$1 for ((i=0; i<${#_CONFIG[@]}; i+=2)) do - echo ${_CONFIG[i]} + if [[ -z ${SECTION} ]] || [[ ${_CONFIG[$i]} =~ ^${SECTION}\.(.+) ]] + then + echo ${_CONFIG[i]} + fi done } @@ -184,18 +198,26 @@ function listAll() { function listSection() { local -i i local SECTION=$1 - for ((i=0; i<${#_CONFIG[@]}; i+=2)) - do - if [[ ${_CONFIG[$i]} =~ ^${SECTION}\.(.+) ]] - then - echo ${_CONFIG[i]} ${_CONFIG[((i+1))]} - fi - done + if [[ -n ${SECTION} ]] + then + for ((i=0; i<${#_CONFIG[@]}; i+=2)) + do + if [[ ${_CONFIG[$i]} =~ ^${SECTION}\.(.+) ]] + then + echo ${_CONFIG[i]} ${_CONFIG[((i+1))]} + fi + done + else + for ((i=0; i<${#_SECTION[@]}; i++)) + do + echo ${_SECTION[i]} + done + fi } # getProperty [name|section.name] # -# Print value for given property (sepcified as $1) +# Print value for given property (sepcified as $1) # Properties without a section can be queried directly as # "name" (rather than ".name") # @@ -218,7 +240,7 @@ function getProperty() { # getPropertyVar [name|section.name] # -# Save value for given property (sepcified as $2) +# Save value for given property (sepcified as $2) # into shell variable (specified as $1) # Properties without a section can be queried directly as # "name" (rather than ".name") @@ -244,20 +266,19 @@ function getPropertyVar() { function testIniParser() { echo $ parseIniFile \< test/t2.ini - parseIniFile < test/t2.ini + parseIniFile < ./test/t2.ini echo $ listKeys listKeys echo $ listAll listAll echo $ listSection section1 - listSection section1 - echo $ getProperty global - getProperty global - echo $ getProperty section2.xyz - getProperty section2.xyz + listSection + echo $ getProperty abc + getProperty abc + echo $ getProperty section1.abc + getProperty section1.abc echo $ getPropertyVar XYZ section2.xyz \&\& echo OK getPropertyVar XYZ section2.xyz && echo OK echo $ echo ">\${XYZ}<" echo ">${XYZ}<" } -