I need to have an array for each "section" in the file containing:
[array0]
value1=asdf
value2=jkl
[array1]
value1=1234
value2=5678
I want to be able to retrieve these values like this:
echo ${array0[value1]}
echo ${array0[value2]}
echo ${array1[value1]}
echo ${array1[value2]}
Any thoughts on how to accomplish this? (Explanations would be a bonus)
I've already read these anwsers but none do exactly what I want to do.
Read a config file in BASH without using "source"
with bash v4, using associative arrays, store the properties from the config file as actual bash variables:
$ while read line; do
if [[ $line =~ ^"["(.+)"]"$ ]]; then
arrname=${BASH_REMATCH[1]}
declare -A $arrname
elif [[ $line =~ ^([_[:alpha:]][_[:alnum:]]*)"="(.*) ]]; then
declare ${arrname}[${BASH_REMATCH[1]}]="${BASH_REMATCH[2]}"
fi
done < config.conf
$ echo ${array0[value1]}
asdf
$ echo ${array1[value2]}
5678
$ for i in "${!array0[@]}"; do echo "$i => ${array0[$i]}"; done
value1 => asdf
value2 => jkl
$ for i in "${!array1[@]}"; do echo "$i => ${array1[$i]}"; done
value1 => 1234
value2 => 5678
One eval
-free, 100% pure Bash possibility:
#!/bin/bash
die() {
printf >&2 "%s\n" "$@"
exit 1
}
aryname=''
linenb=0
while read line; do
((++linenb))
if [[ $line =~ ^[[:space:]]*$ ]]; then
continue
elif [[ $line =~ ^\[([[:alpha:]][[:alnum:]]*)\]$ ]]; then
aryname=${BASH_REMATCH[1]}
declare -A $aryname
elif [[ $line =~ ^([^=]+)=(.*)$ ]]; then
[[ -n aryname ]] || die "*** Error line $linenb: no array name defined"
printf -v ${aryname}["${BASH_REMATCH[1]}"] "%s" "${BASH_REMATCH[2]}"
else
die "*** Error line $linenb: $line"
fi
done
Reads on standard input. If you want to read from a file, change the done
by:
done < "filename"
Lines of the form
space and funnŷ sÿmbòl=value that will have an equal sign: look = it's funny
are allowed
You can declare array in bash scripts with
declare -a <array_name>=(value1 value2 value 3)
Then you can use them like this
echo ${<array_name>[index]}
Edit:
Ok, to construct arrays from config file. I would recommend to have a different file for each array you would like to create.
So here are the steps
1.config file (create a file and place your values in it)
100 200 300
2.script file (read values from file and prepare an array)
array=() #setup array while IFS=$'\n' read -a config do array+=(${config}) done < file_name #access values echo ${array[0]} echo ${array[1]}
IFS denotes the delimiter
-a specifies the array name you want to extract to, so that you can access them inside the while loop.
I am about to go out, but I think you can do something like this (untested) and maybe someone clever , like @anubhava, will pick it up and finish it off...
eval $(gawk -F= '/^\[/{name=gensub(/\[|\]/,"","g");x=0} /=/{print "name[",x++,"]=",$2," "}' config)
Basically, when it sees a line starting with "[
" it picks up the array name in the variable name
and strips off the square brackets with gensub()
. Then, when it sees a line with "=
" in it, it outputs the array name and an increasing index "x
" for eval
to pick up.
Gotta dash - look at the examples for stat -s
here.
来源:https://stackoverflow.com/questions/23167047/bash-parse-arrays-from-config-file