I’m writting a Juju charm to automate the deployment of jhbuild. This system can use different configuration files with sometimes very little difference between them. So, I wanted a basic templating system to manage these files that could run on a minimal system.
The very limited features I needed were file inclusion and variable substitution.

Basically what I wanted is, if I have the following 3 files:
file1.txt

A
${VAR1}
#include file2.txt
B

file2.txt

AA
#include file3.txt
${VAR2}
BB

file3.txt

AAA
BBB

The expected result with VAR1=’this is var1′ and VAR2=’this is var2′ is:

A
this is var1
AA
AAA
BBB
this is var2
BB
B

I went for bash and here is the result:

#!/bin/bash
merge_template () {
    # Merge template files and do variable substitution
    #
    # $1: Template file
    #
    # Supported directives:
    #   #include filename : Include filename and process it.
    #   ${variable}       : substituted by the value of the variable.
    #
    [ -z "$1" ] && return
    set -f
    while IFS='' read -r line; do
        if [[ "$line" =~ \#include\ (.*) ]]; then
            $FUNCNAME ${BASH_REMATCH[1]}
        else
            while [[ "$line" =~ (\$\{[a-zA-Z_][a-zA-Z_0-9]*\}) ]] ; do
                LHS="${BASH_REMATCH[1]}"
                RHS="$(eval echo "\"$LHS\"")"
                line="${line//$LHS/$RHS}"
            done
            printf "%s\n" "$line"
        fi
    done<$1
    set +f
}

merge_template $1

Save it to merge_templates and run it with:

VAR1="This is var1" VAR2="this is var2" ./merge_templates file2.txt

Et voilà