I have a skeleton text file with placeholder strings:
blah blah blah
blah $PLACEHOLDER_1$
blah
$PLACEHOLDER_2$
and so on. Specific "form" of placeholders does not matter -- I may change them to whatever most comfortable for specific implementation.
I have a bash script where I know values for placeholders, and I need to generate a new file, with placeholders replaced with values.
#! /bin/sh
PLACEHOLDER_1 = 'string 1'
PLACEHOLDER_2 = 'multiline
string
2'
# TODO: Generate file output.txt from file output.template
# using placeholders above.
I may do this in multiple passes with sed, but it is not fun. I do not want to use Perl. I want to use textutils and bash itself only.
What is the best way to do what I want in a single pass?
Building on the previous answer, perhaps use an array and compute the sed string?
Seems to fail on the multi-line strings, though.
I don't know how portable Bash arrays might be. Above snippet tested with "GNU bash, version 3.2.17(1)-release (i386-apple-darwin9.0)"
My bash only solution:
Here's a way to do it without sed:
First, a slightly modified template file in which the placeholders are bash variables:
And the script:
Here's a version that demonstrates a template contained within the script, but with a twist. It also demonstrates default values, which can also be used in the template file version, plus you can do math in the template:
No sed, no loops, just hairy nesting and quotes. I'm pretty sure all the quoting will protect you from malicious stuff in a template file, but I'm not going to guarantee it.
I just stumbled upon this question because I was just looking for the exact same, and I found
envsubst(1)
.You can use envsubst if you don't mind using environment variables:
If you have a lot of variables you can store them in a file and just
source
it (remember to useexport
at the end of the sourced file!)You can still use sed to do the replace in a single pass. You just need to specify all the replacements in one command.
eg.