Resolve variable in bash

Viewed 78

I have a file contains a few lines, and in some lines there is a variable like this:

The-first-line
The-second-${VARIABLE}-line
The-third-line

In a bash scrip, I want to read the lines and resolve the variable wherever exists.

VARIABLE=Awesome
LINES=$(echo $(cat file.txt))
for i in $LINES
do :
  echo "$i"
done

The output is same as the input file (unresolved variables) but I want something like this:

The-first-line
The-second-Awesome-line
The-third-line

Thanks in advance for any help!

3 Answers

You can try the following (with a recent enough version of bash that supports namerefs):

while IFS= read -r line; do
  while [[ "$line" =~ (.*)\$\{([^}]+)\}(.*) ]]; do
    declare -n var="${BASH_REMATCH[2]}"
    printf -v line '%s%s%s' "${BASH_REMATCH[1]}" "$var" "${BASH_REMATCH[3]}"
  done
  printf '%s\n' "$line"
done < file.txt

In the innermost loop we iterate as long as there is a ${VARIABLE} variable reference, that we replace by the variable's value, thanks to BASH_REMATCH, the var nameref and the -v option of printf.

Warning: if you have a variable named, e.g., VARIABLE and which value is literally ${VARIABLE}, this script will enter an infinite loop.

If you export your variable you may find envsubst does what you want (eg, How to substitute shell variables in complex text files).

For this particular case:

$ export VARIABLE='Awesome'  # or: VARIABLE='Awesome'; export VARIABLE
$ envsubst < file.txt
The-first-line
The-second-Awesome-line
The-third-line

A quick way to do this would be using the sed command to replace ${variable} in the line with $VARIABLE. Make sure to escape the $ in ${VARIABLE} so it doesn't think it's an actual variable. And to use double quotes so it references the variable in $VARIABLE.

VARIABLE=Awesome
LINES=$(echo $(cat var_file))
for i in $LINES
do :
  echo $i | sed "s/\${VARIABLE}/$VARIABLE/"
done

Let me know if this works for you or if you have any questions.

Related