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
$(<input.txt)
$EOF
)\""
a = 1
b = 2
Note we use $EOF
to minimize conflicting cat's here-document with input.txt content.
Both examples from: https://gist.github.com/4288846
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
Have you tested your second solution? Won't each reference to
$RANDOM
generate possibly different numbers? When I typeecho $RANDOM $RANDOM
in a terminal, I get two different numbers. – Victor – 2014-11-17T15:00:31.207You are right. It produces 2 random number and that heredoc will never close. I will edit it to fix. Thanks! – caruccio – 2014-11-17T19:03:01.797