Replace environment variables in a file with their actual values?
You could use envsubst
(part of gnu gettext
):
envsubst < infile
will replace the environment variables in your file with their corresponding value. The variable names must consist solely of alphanumeric or underscore ASCII characters, not start with a digit and be nonempty; otherwise such a variable reference is ignored.
To replace only certain environment variables, see this question.
This is not very nice but it works
( echo "cat <<EOF" ; cat config.xml ; echo EOF ) | sh
If it was in a shell script it would look like:
#! /bin/sh
cat <<EOF
<property>
<name>instanceId</name>
<value>$INSTANCE_ID</value>
</property>
EOF
Edit, second proposal:
eval "echo \"$(cat config.xml)\""
Edit, not strictly related to question, but in case of variables read from file:
(. .env && eval "echo \"$(cat config.xml)\"")
If you happen to have Perl (but not gettext and envsubst
) you can do the simple replacement with a short script:
$ export INSTANCE_ID=foo; export SERVICE_NAME=bar;
$ perl -pe 's/\$([_A-Z]+)/$ENV{$1}/g' < config.xml
<property>
<name>instanceId</name>
<value>foo</value>
</property>
<property>
<name>rootPath</name>
<value>/services/bar</value>
</property>
I assumed the variable names will only have uppercase letters and underscores, but the first pattern should be easy to alter as needed.
$ENV{...}
references the environment Perl sees.
If you want to support the ${...}
syntax or throw an error on unset variables, you'll need some more work. A close equivalent of gettext
's envsubst
would be:
perl -pe 's/\$(\{)?([a-zA-Z_]\w*)(?(1)\})/$ENV{$2}/g'
Though I feel that feeding variables like that via the process environment seems a bit iffy in general: you can't use arbitrary variables in the files (since they may have special meanings), and some of the values could possibly have at least semi-sensitive data in them.