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"
BASH Parsing variables from config file
Array like data structure in bash (config file)?
The read command has the -a option that allows us to populate the given array with a list of whitespace-delimited values. (The IFS value determines the delimiter, which is whitespace by default.) The array is populated starting at index 0. The last value provided becomes the last element in the array.
conf file in Linux, first locate it in the file system. Most often, the dhclient. conf file will be located in the /etc or /etc/DHCP directory. Once you find the file, open it with your favorite command-line editor.
The /etc/bashrc file might be referred to in /etc/profile or in individual user shell initialization files. The source contains sample bashrc files, or you might find a copy in /usr/share/doc/bash-2.05b/startup-files.
The source command reads and executes commands from the file specified as its argument in the current shell environment. It is useful to load functions, variables, and configuration files into shell scripts. source is a shell built-in in Bash and other popular shells used in Linux and UNIX operating systems.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With