テンプレートのプレースホルダを置き換える

テンプレートのプレースホルダを置き換える

次のシェル構成ファイルがあるとします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 %>シェルに拡張を実行させます。${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

修正する~によるとStephen Chazerasの口コミ"="記号を含む許容値:

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構文に変換します。 2番目のsedコマンドは、<%= @VAR %>スタイル変数参照を口ひげ{{ VAR }}変数参照に置き換えます。

Fedoraはmustacheパッケージの一部ですrubygem-mustache

または、次のものを使用できます。envsubst(パッケージで提供gettext) 例えば次のようになります。

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

シェルでも変数の割り当てが有効でなければなりません。

答え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つのグループ(\1)を形成し、プレースホルダーを抽出して別のグループ(\2)を形成します。最初のグループに置き換えてから、2番目のグループをドル記号に置き換えます。eval変数を計算して拡張するには、このコマンドを使用します。

関連情報