Assuming we have source_file.json of the following content:
{
"someVar": "__SOME_ENV_VAR__",
"anotherVar": "__ANOTHER_ENV_VAR__",
"yetAnotherVar": "__ONE_MORE_ENV_VAR__"
}
How do I
__([A-Z_]\+)__
([A-Z_]\+)
part) as \1
to the value of the environment variable that matches the capturing group (i.e. SOME_ENV_VAR
, ANOTHER_ENV_VAR
, ONE_MORE_ENV_VAR
)I tried to approach this problem from two different angles (with numerous variations)
sed
sed -i "s/__([A-Z_]\+)__/${\1}/g" source_file.json
env | while IFS='=' read -r key value; do
sed -i "s/__$key__/$value/g"
done
But none of them did particularly work all failing with different kinds of errors or coming short of interpolating the environment variable and outputting something like "someVar": "$SOME_ENV_VAR"
.
None of the posts related to the subject cover this particular case (interpolation of a capturing group). Most of them cover the scenario with specific environment variables to be interpolated known ahead of time.
Note: above has to go into /bin/sh script that has to be executed inside Alpine-based docker container and thus no hassle with basetext package installation (to use
envsubst
) considered as an option
If the /bin/sh
of the image is Bash, then you could use a loop to build a Bash array with the replacement commands, and then call sed
:
replacements=()
while IFS='=' read -r key value; do
replacements+=(-e "s/__${key}__/$value/")
done < <(env)
sed -i "${replacements[@]}" /path/to/file
If it is not Bash, then you could create a sed
script with a loop, and then pass that to sed
(thanks @tripleee for the nudge):
script=/tmp/sed.txt
env | while IFS='=' read -r key value; do
echo "s/__${key}__/$value/"
done > "$script"
sed -f "$script" -i /path/to/file
Both approaches have the weakness that they break if the value
(or the key
) contains the pattern and replace separator /
in the s///
command of sed
. If there is a symbol that is guaranteed to be not used by any key
and value
, then you can use that. For example instead of s///
, the command can be written as s???
.