Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'd like to somehow spit out a file (which has env variable references) and substitute the actual values. This is what I've tried, but as you can see it's not working. Any ideas?

-bash-3.00$ cat vars_file 
-bash-3.00$ export MY_VAR=MY_VALUE; cat ./vars_file | xargs echo
share|improve this question
up vote 6 down vote accepted

Old thread, but this is a recurrent issue. Here is a solution using bash's mapfile:

mateus@mateus:/tmp$ cat input.txt
a = $a
b = $b
mateus@mateus:/tmp$ echo a=$a, b=$b
a=1, b=2
mateus@mateus:/tmp$ function subst() { eval echo -E "$2"; }
mateus@mateus:/tmp$ mapfile -c 1 -C subst < input.txt
a = 1
b = 2

The bash builtin mapfile calls user-defined function subst (see -C/-c options) on each line read from input file input.txt. Since the line contains unescaped text, eval is used tu evaluate it and echo the transformed text to stdout (-E avoid special characters to be interpreted).

IMHO this is a much more elegant than any sed/awk/perl/regex based solution.

Another possible solution is to use shell's own substitution. This looks like a more "portable" way not relaying on mapfile:

mateus@mateus:/tmp$ EOF=EOF_$RANDOM; eval echo "\"$(cat <<$EOF
a = 1
b = 2

Note we use $EOF to minimize conflicting cat's here-document with input.txt content.

Both examples from:

EDIT: Sorry, the first example doesn't handles comments and white space correctly. I'll work on that and post a solution. EDIT2: Fix double $RANDOM eval

share|improve this answer
Have you tested your second solution? Won't each reference to $RANDOM generate possibly different numbers? When I type echo $RANDOM $RANDOM in a terminal, I get two different numbers. – Victor Nov 17 '14 at 15:00
You are right. It produces 2 random number and that heredoc will never close. I will edit it to fix. Thanks! – caruccio Nov 17 '14 at 19:03

As described in the same thread at, the "proper" solution would be as follows:

awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < input.txt > output.txt

eval approach is fine, but tends to fail on XML files for instance.

share|improve this answer

Can be done with script (e.g. file name is

while read line; do eval echo \"$line\"; done < $1 > $2

The script may be called like this:

env VAR1=value1 sh input_file output_file

share|improve this answer
any idea how to do this when there's a paren in the file? -bash: syntax error near unexpected token `(' – andersonbd1 Jan 20 '11 at 17:51
@andersonbd1: I suppose you could replace the parentheses with sed and replace them back later. Otherwise, you might want to consider to remove the accept mark from my answer to get a better awk solution, as the above questions mentions that you can't read the effect with sed. – Tom Wijsman Jan 20 '11 at 18:09
I guess sed is my best bet. It ain't pretty but it'll work. Thanks TomWij – andersonbd1 Jan 20 '11 at 18:24
You might want to quote that variable: echo "$line". @andersonbd1: what is the context of the parentheses? – Dennis Williamson Jan 20 '11 at 19:06
Oops, sorry, I forgot to say that you should use read -r, too. – Dennis Williamson Jan 20 '11 at 19:14

Here's my proposed solution:

eval $'cat <<\002\n'"$(<ifile)"$'\n\002' > ofile

\002 can be replaced with any character or string that doesn't occur in the ifile. To delete any occurrences of the delimiting character in the input file:

eval $'cat <<\002\n'"$(tr -d '\002' < ifile)"$'\n\002' > ofile

This solution seems to resolve most issues but is notably vulnerable to command injection in the template file through $(command) directives.

share|improve this answer

$"xxx" may be a easy way

a=$(< file)
eval b=\$\"$a\"

then "$b" is the expanded text

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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