Reputation: 3920
I have various environment variables declared inside an env_file
referenced in a docker-compose.yml
export FOO=bar
export FAZ=baz
In a config file within a container I reference these environment variables as such:
Today is a great day to ${FOO} and ${FAZ}
I want to be able to capture all instances of text start with ${
and ending with }
(ex. ${<SOMETHING>}
) and then replace it with the environment variable of key <SOMETHING>
.
The following works in the shell, but I cannot get this to work with sed -i
against a file, or within a bash script.
echo "TODAY IS ${DAY}" | sed -r 's/(<foobar>\$[\w{}]+)/<foobar>/g
DAY
is "FUNDAY" would produce: "TODAY IS FUNDAY"
Upvotes: 1
Views: 1676
Reputation: 1190
I think i found something which may interest you. Please note that it complies to using only sed, in place editing and bash. Before we get into it, lets see the input and output:
Environment file/variables: As seen below, our file "myenv"
has 3 variables and their values are as seen below.
%_Host@User> file myenv
myenv: ASCII text
%_Host@User> cat myenv
export FOO='This is FOO'
export BAR='This is BAR'
export BAZ='This is BAZ'
%_Host@User> env|egrep "FOO|BAR|BAZ"
FOO=This is FOO
BAR=This is BAR
BAZ=This is BAZ
%_Host@User>
Target file to perform the operation upon: Our target is to read the file sample.txt
and replace values of variables with their actual values, if they are found in the loaded environment file. Our 4th line is not defined in our variable file so it should be untouched or unchanged.
%_Host@User> cat sample.txt
${FOO} is TRUE
${BAR} is TRUE
${BAZ} is TRUE
${BRAZ} is TRUE
%_Host@User>
SCRIPT Result and final output: To demonstrate, I am printing the lines as they are read from the target file sample.txt
. If the variable inside the container (eg: ${FOO}
is found in any of the line, we replace the it with its value (eg: This is FOO
in this case) which we can obtain from the env
%_Host@User> ./env.sh sample.txt ; cat sample.txt
[1.] Line is: [${FOO} is TRUE]
[1.] VAR:[FOO] has VALUE:[This is FOO]
[2.] Line is: [${BAR} is TRUE]
[2.] VAR:[BAR] has VALUE:[This is BAR]
[3.] Line is: [${BAZ} is TRUE]
[3.] VAR:[BAZ] has VALUE:[This is BAZ]
[4.] Line is: [${BRAZ} is TRUE]
[4.] VAR:[BRAZ] not found and NO CHANGE IN FILE !!
This is FOO is TRUE
This is BAR is TRUE
This is BAZ is TRUE
${BRAZ} is TRUE
%_Host@User>
As seen above, we have managed to change the ${FOO}
with This is FOO
as expected and left any other/s (which were not in our env file) untouched.
SCRIPT and its working:
#!/bin/bash
i=1
cfgfile="$1"
cat $cfgfile | while read line
do
echo "[${i}.] Line is: [$line]"
var=$(echo $line | sed 's#^.*\${\(\w*\)}.*$#\1#g')
val=$(env |grep "$var"| cut -f2 -d"=")
env|grep "${var}=" >/dev/null
if [ $? -eq 0 ]
then
echo "[$i.] VAR:[$var] has VALUE:[$val]"
# Perform inplace editing.
sed -i "s@\${$var}@$val@g" "$cfgfile"
else
echo "[$i.] VAR:[$var] not found and NO CHANGE IN FILE !!"
fi
((i++)) ; echo
done
Above script is following these steps:
i=1
is just our counter. Not so important. Only for demo purpose.cfgfile="$1"
to accept file from prompt.FOO
from ${FOO}
and its actual value from env i.e. This is FOO
and store it in var
and val
. simple enough.FOO
is defined in env
or not and check for command status. $?
is 0
or True
, we go ahead and perform in place editing or else we leave the line alone and no change.I believe you should try your original command with double quotes (") instead of single ('). It should work.
Please let us know if this was any useful.
Cheers.
Upvotes: 1