替换模板中的占位符

替换模板中的占位符

假设我有一个像这样的 shell 配置文件config

HOST=localhost
PORT=8080

template现在我有一个这样的模板:

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

如何用文件template中的值替换占位符?config

我当然可以这样做:

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

但如果有很多配置值,这就变得太麻烦了。我将如何以更通用的方式做到这一点?我想迭代每个占位符并用实际值替换它。

答案1

你可以这样做:

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

也就是说,让 sed在转义所有,和字符后替换所有<%= @xxx %>的,并让 shell 进行扩展。${xxx}$\`

或者,如果您不能保证其中template不包含一行__end_of_template__

eval "cut -c2- << x
$(sed 's/[\$`]/\\&/g;s/<%= @\([^ ]*\) %>/${\1}/g;s/^/y/' < template)
x"

答案2

一个awk办法:

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

更新根据斯蒂芬·查泽拉斯的评论允许值中包含“=”符号:

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

答案3

您可以使用小胡子(1)替换一堆模板变量:

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

管道的第一个元素将您的配置分配转换为我的小胡子可以理解的 YAML 语法。第二个sed命令将<%= @VAR %>样式变量引用替换为小胡子{{ VAR }}变量引用。

在 Fedora 上,mustache是软件包的一部分rubygem-mustache

或者,您可以使用envsubst(由包提供gettext),例如:

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

要求您的变量分配在 shell 中也有效。

答案4

单程:

#!/bin/sh

. config

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

结果:

The host is localhost
The port is 8080

使用sed,我们提取直到“<”的字符并形成一个组(\1),并提取占位符并形成另一个组(\2)。将其替换为第一组,然后用美元符号替换第二组。只需使用该eval命令,就可以计算变量并对其进行扩展。

相关内容