How do I replace placeholders in a file with variables from another file? (Like docker-compose is doing it.)

I found many articles about single variable replacements or replacement by environment variables but not file to file.

.env file


Content file

Hello "${name}"! I wait for u since ${time}.

Output file:

Hello "John"! I wait for u since 10:00.

Edit: Note that I also want to keep the " in the file.

Edit2: I ended up using the solution from @steeldriver. This is what I use now in my script:

# Make copy of the template folder (containing scripts and `.env` file)
cp -r templates .templates

# Replace environment variables in all files of the folder
set -a
for file in $(find .templates -type f)
    . ./.env && envsubst < $file > $file.tmp && mv $file.tmp $file
set +a

# create output directory
mkdir -p $HOME/output/

# copy if new or modified
rsync -raz .templates/. $HOME/output/

# remove temp folder
rm -r .templates
  • Consider also moustache, and other templating languages. – ctrl-alt-delor Aug 3 '19 at 13:51

Using envsubst

set -a
. ./.env && envsubst < content
set +a

The set -a / set +a turn on / off automatic export of created/modified variables.


Found a working solution in Replace environment variables in a file with their actual values?

(. .env && eval "echo \"$(cat config.xml)\"")

Edit: This solution removes also " marks in the files. Thats not what I wanted.

  • That would potentially run any command after a " and a ; (or newline, etc.) in the XML file. Better to use envsubst. – Kusalananda Aug 3 '19 at 12:52
  • @Kusalananda can u give an example? I also noticed that " will be removed from my file with this command :( – jwillmer Aug 3 '19 at 13:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.