Issue
Currently, i have a property file like this:
[default]
aa=aa
bb=bb
[dev]
aa=aa
dd=dd
If I want to get a certain value in a section, I can use following code:
awk -F '=' '/\['$section'\]/{a=1}a==1&&$1~/'$key'/{print $2;exit}' $configfile
But How can I get the whole section, e.g. I want a list to hold all values in dev section?
Can any one help with this?
[edit]
I may want the all values in a section to be saved in a list like this:
list=()
list=`get_section dev`
and the list content can be:
aa bb
Thanks again for your kindly help!
Solution
I think the following would be my solution to extract a section:
awk '/^\[/{x=0} $1=="["section"]"{x=1} x' section="$section" my.ini
This avoids any issues with blank lines within a section. It doesn't, however, print the list of results, or turn them into shell variables, which I gather is what you're looking for.
If your shell is bash, you might take advantage of arrays, and avoid the need for awk altogether. Associative arrays are a feature of bash 4:
declare -A conf
while IFS='=' read var val; do
if [[ $var == \[*] ]]; then
section="${var//[^[:alnum:]]/}" # strip invalid chars from variable name
elif [[ -n "$val" ]]; then
echo " > ${section}_$var=$val" # debugging
declare "${section}_$var=$val" # set to vars, bash 3
conf["${section}_$var"]="$val" # store in associative array, bash 4
fi
done < my.ini
This stores your entire configuration in variables or a bash array. If you want to trim leading spaces from your values, the easiest way would be to set IFS='= '
instead of just '='
.
The equivalent in POSIX shell might look something like:
while IFS='=' read var val; do
if expr "$var" : '[[].*[]]$' >/dev/null; then
section="$(echo "$var" | tr -d '][')"
elif [ -n "$val" ]; then
echo " > ${section}_$var=$val" # debugging
eval "${section}_$var=\"$val\"" # set to vars, POSIX
fi
done < my.ini
The result of this would be a set of variables similar to what the declare
bash 3 option above would provide. But with POSIX, we'd be stuck with eval
.
If you want a random-access method to extract a variable from a section in bash, you could do it as a function:
function confitem() {
# Usage: confitem section itemname
local -A conf
local var val section
local retval=1
while IFS='=' read var val; do
if [[ $var == \[*] ]]; then
section="$var"
elif [[ -n $val ]] && [[ $section == $1 ]] && [[ $var == $2 ]]; then
printf '%s' "$val" # print the result
retval=0 # set a return value for the function
break # and quit the loop.
fi
done < my.ini
return $retval
}
Answered By - ghoti Answer Checked By - Senaida (WPSolving Volunteer)