Goal of Program
Consider a template file template.txt
with double brace variables, intended to be replaced by values:
hello there {{ MY_VAR1 }}
some other stuff
some other stuff
foo: {{ MY_VAR2 }}
{{ MY_VAR2 }} is the value of MY_VAR2
and assume you have defined and exported those variables:
export MY_VAR1=val1
export MY_VAR2=val2
we want a script fill_template
such that fill_template template.txt
produces:
hello there val1
some other stuff
some other stuff
foo: val2
val2 is the value of MY_VAR2
and which gives an appropriate error message if any of the required template variables are not defined.
Code for review
Here is working code for fill_template
:
#!/bin/bash
if [[ ! -f $1 ]]; then
>&2 echo "Usage: $0 <filename>"
exit 1
fi
# Gather all the required template variables
vars=()
while IFS= read -r line; do
vars+=( "$line" )
done < <( awk 'match($0, /{{ (.*) }}/, a) { print a[1] }' "$1" | sort -u )
# Verify that all template variables are set and exported
missing=()
for var in "${vars[@]}"; do
if [[ -z ${!var+x} ]]; then
missing+=( "$var" )
fi
done
if [[ ${#missing[@]} -gt 0 ]]; then
>&2 echo "The following required variables have not been set and exported:"
for var in "${missing[@]}"; do
>&2 echo "${var}"
done
exit 1
fi
# Dynamically construct the sed cmd to do the replacement
sed_cmd=
for var in "${vars[@]}"; do
sed_cmd+="s/\\{\\{ *${var} *}}/${!var}/g;"
done
sed -E "${sed_cmd}" "$1"
Notes
- All comments welcome, from the high-level approach to nitpicks.
- Currently we assume there will be only one
{{ TEMPLATE_VAR }}
per line