Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash Parse Arrays From Config File

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)?

like image 303
AJ Ferguson Avatar asked Apr 19 '14 07:04

AJ Ferguson


People also ask

How do I read an array file in bash?

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.

How do you read a .conf file in Linux?

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.

Where is bash config file?

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.

What does source mean in bash?

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.


2 Answers

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
like image 143
glenn jackman Avatar answered Oct 20 '22 01:10

glenn jackman


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

like image 20
gniourf_gniourf Avatar answered Oct 19 '22 23:10

gniourf_gniourf