Sunday, May 14, 2017

Reading INI Files

This article is about how to read ini files in Bash.

Assume we want to read the blogger key from the Links section in the following sample.ini to get the value http://bashmasterclass.blogspot.com.au/:

[Name]
firstname=Stephen
lastname=Quan

[Links]
github=https://github.com/stephenquan/BashMasterClass
blogger=http://bashmasterclass.blogspot.com.au/

The following awk script:

cat sample.ini | tr -d '\r' | awk '
/^\[.*\]$/ { section=$0 }
/=/ { print section $0 }
'

transforms sample.ini file into [SECTION]NAME=VALUE format:

[Name]firstname=Stephen
[Name]lastname=Quan
[Links]github=https://github.com/stephenquan/BashMasterClass
[Links]blogger=http://bashmasterclass.blogspot.com.au/

Now, we can use grep and sed to lookup the blogger key in the Links section:

key=blogger
section=Links

value=$(cat sample.ini | tr -d '\r' | awk '
/^\[.*\]$/ { section=$0 }
/=/ { print section $0 }
' | grep '^\['$section'\]'$key'=' | sed 's/^[^=]*=//')

echo $value # Outputs: http://bashmasterclass.blogspot.com.au/

Tuesday, April 25, 2017

Nested Variable Expansion

This article is about Bash's indirection syntax: ${!VARIABLE}. The exclamation point tells Bash to expand the value of VARIABLE twice. For example

VARIABLE=aa
aa=bb
echo ${VARIABLE} # Outputs: aa
echo ${!VARIABLE} # Outputs: bb

Whilst already cool, we often want to expand an expression, for example:

ANIMAL=CAT
BABYCAT=KITTEN
TMP=BABY${ANIMAL} # TMP=BABYCAT
echo ${!TMP} # Outputs: KITTEN

To do the Bash's indirection we needed to make use of a temporary variable. If we tried to do it in one line, we would encounter a bad substitution error:

ANIMAL=CAT
BABYCAT=KITTEN
echo ${!BABY${ANIMAL}} # Outputs: ${!BABY${ANIMAL}}: bad substitution

You can work around this limitation because Bash's indirection syntax works on argument variables (i.e. $1, $2, etc.) within a Bash function:

function deref { echo ${!1} ; }
ANIMAL=CAT
BABYCAT=KITTEN
deref BABY${ANIMAL} # Outputs: KITTEN

A cool thing about implementing Bash indirection as a function, is, you can call it nested manner to expand your variable as many times as you want:

function deref { echo ${!1} ; }
AA=BB
BB=CC
CC=Hello
echo ${AA} # Outputs: BB
deref ${AA} # Outputs: CC
deref $(deref ${AA}) # Outputs: Hello

Reading INI Files

This article is about how to read ini files in Bash. Assume we want to read the blogger key from the Links section in the follo...