0

I have a configuration script which does basically this:

#!/bin/bash

source vars.sh

cat >foo.output <<EOF
# some static stuff (many lines...)
variable_bit=($SOME_VAR, $SOME_OTHER_VAR, ...)
# some more static stuff (many lines...)
EOF

It would be nicer to have some other file, call it foo.output.template, which looked like this

# some static stuff (many lines...)
VARIABLE_BIT
# some more static stuff (many lines...)

Then, my configuration script could do something like this

sed 's/VARIABLE_BIT/<<STDIN>>/' foo.output.template >foo.output <<EOF
variable_bit=($SOME_VAR, $SOME_OTHER_VAR, ...)
EOF

This won't work, and I don't know if sed can do this, but the intention is that it

  • reads foo.output.template
  • matches VARIABLE_BIT
  • replaces this with whatever is in stdin
  • then pipes to foo.output

Can sed, awk, or some other common *nix utility do this easily?

  • Maybe (read -r line; sed "s/VARIABLE_BIT/$line/" ... ) << ... – Mark Plotnick Jun 19 '18 at 20:47
  • I'm sure this must be a duplicate - you can do something like cat foo | sed -e '/VARIABLE_BIT/{r /dev/stdin' -e 'd;}' foo.output.template > foo.output – steeldriver Jun 19 '18 at 22:16
  • @steeldriver That looks promising, can you please unpack what you wrote? – spraff Jun 20 '18 at 8:49
  • @spraff I have outlined an answer below – steeldriver Jun 20 '18 at 12:40
1

At least if you have GNU sed, then given

$ cat foo.output.template
# some static stuff (many lines...)
VARIABLE_BIT
# some more static stuff (many lines...)

and

$ cat bar
hello
hello

then you can match VARIABLE_BIT, read and insert the contents of bar, then delete VARIABLE_BIT:

$ cat bar | sed '/^VARIABLE_BIT/{
r /dev/stdin
d
}' foo.output.template
# some static stuff (many lines...)
hello
hello
# some more static stuff (many lines...)

You can make it into a one-liner if you are careful to avoid the d being interpreted as part of the filename

cat bar | sed -e '/^VARIABLE_BIT/{r /dev/stdin' -e 'd;}' foo.output.template

Redirect to an output file in the usual way i.e. > foo.output


Note: I have used cat bar just to illustrate standard input; if you really want to use a file for the replacement text, then you can do that directly i.e.

sed -e '/^VARIABLE_BIT/{r bar' -e 'd;}' foo.output.template > foo.output
0

Can't you split your template into two files, one before the variable part and one after it? The shell can then concatenate them like this:

( cat foo.output.template.before; cat ; cat foo.output.template.after; ) >foo.output
  • That would be the easy hack, I'm curious as to whether there's a neat all-in-one solution. – spraff Jun 19 '18 at 21:38
  • If there are no backspace (\b) characters in your input, then here you are: sed -e "s/VARIABLE_BIT/$(tr '\n' '\b' | sed 's/.$//')/" foo.output.template | tr '\b' '\n' – Renardo Jun 20 '18 at 6:42
0
cat before.input - after.input >output <<EOF
whatever $FOO $BAR
EOF

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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