Parse Multi-Section Configuration File

Hello all,

Sample configuration file:

[NETWORK-CAMERA.C1]
username = root
password = admin
IpAddress = 192.168.2.90
HttpCommand = /getfile?hello.jpg
[DATA-CENTER.S1]
Username = root2
Password = admin2
Passive = no
Host = 192.168.1.100
Path = /uploads
[DATA-CENTER.S2]
Username = root3
Password = adming
Passive = no
Host = 192.168.1.101
Path = /uploads

Can someone help me parse this configuration file by calling a section e.g DATA-CENTER.S2 and have it output key-value to an array?

$ X=($(awk '/\[/ { p = 0 } /\[DATA-CENTER.S2]/ { p = 1; next } {sub(/.* *= */, "")} p' file1))

$ echo ${X[@]}
root3 adming no 192.168.1.101 /uploads

$ echo ${X[0]}
root3

$ echo ${X[1]}
adming


$ Y=($(sed -n "/\[DATA-CENTER.S2]/,/\[/ {/\[/d;s/.* *= *//;p;}" file1))

$ echo ${Y[@]}
root3 adming no 192.168.1.101 /uploads

$ echo ${Y[0]}
root3

$ echo ${Y[1]}
adming

slick, thank you so much!

---------- Post updated at 01:33 PM ---------- Previous update was at 11:20 AM ----------

ok this is odd...when I try it within the console it works fine but when I try it within a schell (.sh) script I get syntax error.

my_array=( one two three )

syntax error �(� unexpected

even with a simple array test I get the same error, any ideas...

Which shell are you using - and how are you running the script?

i.e.

./my_script

or

sh ./my_script

configured it out...

I had #!/bin/sh and once I changed it to #!/bin/bash it worked.

For old shell try:

#!/bin/sh
set -- $(awk '/\[DATA-CENTER.S1]/{f=1;next}/\[/{f=0}f{print $NF}' file)
echo $@
echo $1

Haven�t touched shell in years, but it�s fun to get back into it (missed scratching my head), LOL!

Thanks again everyone...

---------- Post updated at 05:49 PM ---------- Previous update was at 01:59 PM ----------

I should have provided additional value scenarios but the above is not parsing the following key-values:

[STATION]
Region = NL
Organization = NLDOT
StationName = "Chateau Pond"
StationClientId = NLPCP
StationNetworkId = NLDOT_NLPCP
[NETWORK-CAMERA.C1]
Username = root
Password = admin
Host = 192.168.2.90
HttpCommand = /axis-cgi/jpg/image.cgi?resolution=320x240
Retries = 3
[DATA-CENTER.S1]
Username = root2
Password = admin2
Passive = no
Host = 192.168.1.100
Path = /uploads
[DATA-CENTER.S2]
Username = root3
Password = admin3
Passive = no
Host = 192.168.1.101
Path = /upload

any assistance would be greatly appreciated.

Because of the spaces?

Maybe in simple shell is easier...

$ cat Test
SECTION=${1:-"STATION"}
X=0
while IFS=\= read LVAL RVAL; do
  case "$LVAL" in
   "[$SECTION]") P=1; continue;;
   "["*) P=0; continue
  esac
  [ P -eq 1 ] && VALUE[$X]=$RVAL && X=$((X + 1))
done < file1

echo All:  ${VALUE[@]}
echo Val1: ${VALUE[0]}
echo Val2: ${VALUE[1]}
echo Val3: ${VALUE[2]}

$ ./Test
All:  NL NLDOT "Chateau Pond" NLPCP NLDOT_NLPCP
Val1: NL
Val2: NLDOT
Val3: "Chateau Pond"

Or using the original sed:

$ cat Test
X=0
sed -n "/\[STATION]/,/\[/ {/\[/d;s/.* *= *//;p;}" file1 | while read LINE; do
  A[$X]=$LINE
  X=$((X + 1))
done

echo ${A[@]}
echo ${A[0]}
echo ${A[1]}
echo ${A[2]}

$ ./Test
NL NLDOT "Chateau Pond" NLPCP NLDOT_NLPCP
NL
NLDOT
"Chateau Pond"

I tried the sed version but encountering two problems

	X=0
	sed -n "/\[NETWORK-CAMERA.C1]/,/\[/ {/\[/d;s/.* *= *//;p;}" ../etc/app.conf | while read LINE; do 
		A[$X]=$LINE 
		echo ${A[$X]} 
		X=$((X + 1)) 
		done
	#
	echo ${A[@]}

I can see the values in the array while it loops but when I try to see all (@) it is empty. The other issue is with path values having more than one / slash. I assume it is with the reg expr being used but I cant figure out why the array is empty.

In bash the pipe | before while creates a sub shell. One of your records has an = sign in the value part, that's confusing it.

  while read LINE; do
    A[$X]=$LINE
    echo ${A[$X]}
    X=$((X + 1))
    done < <(sed -n "/\[STATION]/,/\[/ {/\[/d;s/.* *= //;p;}" file1)
  #
  echo ${A[@]}

Have you tried the solution of danmero?