Substituir espaços reservados no modelo

4

Digamos que eu tenha um arquivo de configuração do shell config assim:

HOST=localhost
PORT=8080

Agora eu tenho um modelo template como este:

The host is <%= @HOST %>
The port is <%= @PORT %>

Como eu substituo placeholders em template por valores em config file?

Eu certamente posso fazer assim:

$ . config
$ sed -e "s/<%= @HOST %>/$HOST/" \
> -e "s/<%= @PORT %>/$PORT/" < template
The host is localhost
The port is 8080

Mas se houver muitos valores de configuração, isso se torna muito complicado. Como eu faria isso de maneira mais genérica? Gostaria de fazer uma iteração sobre cada espaço reservado e substituí-lo por um valor real.

    
por Maxim 06.12.2012 / 12:24

4 respostas

4

Você pode fazer algo como:

eval "cat << __end_of_template__
$(sed 's/[\$']/\&/g;s/<%= @\([^ ]*\) %>/${}/g' < template)
__end_of_template__"

Ou seja, o sed substitui todos os <%= @xxx %> por ${xxx} depois de ter escapado todos os caracteres $ , \ e ' e deixe o shell fazer a expansão.

Ou se você não pode garantir que template não contenha uma linha __end_of_template__ :

eval "cut -c2- << x
$(sed 's/[\$']/\&/g;s/<%= @\([^ ]*\) %>/${}/g;s/^/y/' < template)
x"
    
por 06.12.2012 / 14:43
3

Uma awk way:

awk -F= 'FNR==NR{v[$1]=$2;next};{for(p in v)gsub("<%= @"p" %>",v[p])};1' config template

Atualizado de acordo com o comentário de Stephane Chazelas para permitir "=" sinais nos valores:

awk -F= 'FNR==NR{v[$1]=substr($0,length($1)+2);next};{for(p in v)gsub("<%= @"p" %>",v[p])};1' config template
    
por 06.12.2012 / 14:20
2

Você pode usar o bigode (1) para substituir um monte de variáveis de modelo:

$ { echo ---; sed 's/=/: /' config; echo --- } \
  | mustache - <(sed -e 's/<%= @/{{/g' -e 's/%>/}}/g' template)

O primeiro elemento do pipe traduz suas atribuições de configuração para a sintaxe YAML que compreende meu bigode. O segundo comando sed substitui as referências da variável <%= @VAR %> style pelo bigode {{ VAR }} ones.

No Fedora, mustache é parte do pacote rubygem-mustache .

Como alternativa, você pode usar envsubst (fornecido pelo gettext package), por exemplo:

$ ( export $(cat config) ; sed -e 's/<%= @\([^%]*\) %>/${}/g' template 
  | envsubst )

Requer que suas atribuições de variáveis também sejam válidas no shell.

    
por 11.03.2017 / 15:32
-1

Um caminho:

#!/bin/sh

. config

while read line
do
        eval echo $(echo $line | sed "s/\([^<]*\)<%= @\([^ ]*\) %>/ \$/")
done < template

Resultados:

The host is localhost
The port is 8080

Usando sed , extraímos os caracteres até '<' e formar um grupo ( ), e extrair o espaço reservado e formar outro grupo ( ). Este é substituído pelo 1º grupo e depois o símbolo do dólar seguido pelo 2º grupo. Apenas usando o comando eval , a variável pode ser avaliada e expandida.

    
por 06.12.2012 / 12:38