espaços reservados preencher arquivo em única passagem
Pergunta
Eu tenho um arquivo de texto esqueleto com cordas de espaço reservado:
blah blah blah
blah $PLACEHOLDER_1$
blah
$PLACEHOLDER_2$
e assim por diante. Específica "forma" de espaços reservados não importa -. Eu posso mudá-los a qualquer mais confortável para implementação específica
Eu tenho um script onde eu sei valores para espaços reservados, e eu preciso gerar um novo arquivo, com espaços reservados substituídos por valores.
#! /bin/sh
PLACEHOLDER_1 = 'string 1'
PLACEHOLDER_2 = 'multiline
string
2'
# TODO: Generate file output.txt from file output.template
# using placeholders above.
Eu posso fazer isso em várias passagens com sed, mas não é divertido. Eu faço não quiser usar Perl. Quero textutils uso e bater-se apenas.
Qual é a melhor maneira de fazer o que eu quero em uma única passagem?
Solução
Você pode ainda usam sed para fazer a substituição em uma única passagem. Você só precisa especificar todas as substituições em um comando.
por exemplo.
sed -i 's/PLACEHOLDER_1/string 1/g;s/PLACEHOLDER_2/string 2/g' <file>
Outras dicas
Aqui está uma maneira de fazê-lo sem sed:
Primeiro, um arquivo de modelo ligeiramente modificada em que os espaços reservados são variáveis ??festança:
blah blah blah
blah $PLACEHOLDER_1
blah
$PLACEHOLDER_2
E o script:
#! /bin/sh
templatefile=output.template
outputfile=output.txt
PLACEHOLDER_1='string 1'
PLACEHOLDER_2='multiline
string
2'
# DONE: Generate file output.txt from file output.template
# using placeholders above.
echo "$(eval "echo \"$(cat $templatefile)\"")" > $outputfile
Aqui está uma versão que demonstra um modelo contido no script, mas com uma torção. Ele também demonstra valores padrão, que também podem ser usados ??na versão arquivo de modelo, mais você pode fazer matemática no modelo:
#! /bin/sh
template='blah blah blah
blah $PLACEHOLDER_1
blah
${PLACEHOLDER_2:-"some text"} blah ${PLACEHOLDER_3:-"some
lines
of
text"} and the total is: $((${VAL_1:-0} + ${VAL_2:-0}))'
# default operands to zero (or 1) to prevent errors due to unset variables
outputfile=output.txt
# gears spin, bells ding, values for placeholders are computed
PLACEHOLDER_1='string 1'
PLACEHOLDER_2='multiline
string
2'
VAL_1=2
VAL_2=4
unset PLACEHOLDER_3 # so we can trigger one of the defaults
# Generate file output.txt from variable $template
# using placeholders above.
echo "$(eval "echo \"$template\"")" > $outputfile
No sed, sem loops, apenas nidificação peludo e citações. Tenho certeza de que todos os citando o protegerá de coisas mal-intencionado em um arquivo de modelo, mas eu não estou indo para garanti-lo.
Com base na resposta anterior, talvez usar uma matriz e calcular a string sed?
#!/bin/sh
PLACEHOLDER[0]='string 1'
PLACEHOLDER[1]='multiline
string
2'
s="sed -i "
for(( i=0 ; i<${#PLACEHOLDER[*]} ; i++ )) ; do
echo ${PLACEHOLDER[$i]}
s=$s"s/PLACEHOLDER_$i/${PLACEHOLDER[$i]}/g;"
done
echo $s
parece falhar nas cordas multi-linha, no entanto.
Eu não sei como portátil matrizes Bash pode ser. Acima snippet testado com "GNU bash, versão 3.2.17 (1) -release (i386-maçã-darwin9.0)"
Meu festa única solução:
TEMPLATE='
foo
$var1
bar
$var2'
eval "echo \"$TEMPLATE\""
Eu só tropeçou em esta pergunta porque eu estava apenas procurando exatamente o mesmo, e eu achei envsubst(1)
.
Você pode usar envsubst se você não se importa com as variáveis ??de ambiente:
PLACEHOLDER_1='string 1' PLACEHOLDER_2='multiline
string
2' envsubst < output.template
Se você tem um monte de variáveis ??que você pode armazená-los em um arquivo e apenas source
-lo (lembre-se de usar export
no final do arquivo source!)