Muitas das respostas usando eval
e echo
tipo de trabalho, mas quebram em várias coisas, como várias linhas, tentativa de escape de metacaracteres shell, escapes dentro do modelo que não se destina a ser expandido por bash, etc.
Eu tive o mesmo problema e escrevi esta função shell, que pelo que eu posso dizer, lida com tudo corretamente. Isso ainda removerá apenas as novas linhas finais do modelo, por causa das regras de substituição de comandos do bash, mas nunca achei que isso fosse um problema, desde que tudo o mais permanecesse intacto.
apply_shell_expansion() {
declare file="$1"
declare data=$(< "$file")
declare delimiter="__apply_shell_expansion_delimiter__"
declare command="cat <<$delimiter"$'\n'"$data"$'\n'"$delimiter"
eval "$command"
}
Por exemplo, você pode usá-lo assim com um parameters.cfg
que é realmente um script de shell que apenas define variáveis e um template.txt
que é um modelo que usa essas variáveis:
. parameters.cfg
printf "%s\n" "$(apply_shell_expansion template.txt)" > result.txt
Na prática, eu uso isso como uma espécie de sistema de template leve.
eval
.