質問

プレースホルダー文字列を含むスケルトンテキストファイルがあります:

blah blah blah
blah $PLACEHOLDER_1$
blah
$PLACEHOLDER_2$

など。特定の「フォーム」プレースホルダーは重要ではありません。特定の実装に最も適したものに変更できます。

プレースホルダーの値を知っているbashスクリプトがあり、プレースホルダーを値に置き換えて新しいファイルを生成する必要があります。

#! /bin/sh
PLACEHOLDER_1 = 'string 1'
PLACEHOLDER_2 = 'multiline 
string 
2'
# TODO: Generate file output.txt from file output.template 
#       using placeholders above.

これはsedを使用して複数のパスで実行できますが、面白くありません。 Perlを使用したくないしない。 textutilsとbashのみを使用したい。

1回のパスで必要なことを行う最良の方法は何ですか?

役に立ちましたか?

解決

1回のパスでsedを使用して置換を実行できます。 1つのコマンドですべての置換を指定する必要があります。

eg。

sed -i 's/PLACEHOLDER_1/string 1/g;s/PLACEHOLDER_2/string 2/g' <file>

他のヒント

sedを使用せずに実行する方法は次のとおりです。

最初に、プレースホルダーがbash変数であるわずかに変更されたテンプレートファイル:

blah blah blah
blah $PLACEHOLDER_1
blah
$PLACEHOLDER_2

そしてスクリプト:

#! /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

これは、スクリプト内に含まれているテンプレートをデモンストレーションするバージョンですが、ひねりが加えられています。また、テンプレートファイルバージョンでも使用できるデフォルト値に加えて、テンプレートで数学を実行できます。

#! /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

sedなし、ループなし、毛むくじゃらのネストと引用符のみ。すべての引用がテンプレートファイル内の悪意のあるものからあなたを保護すると確信していますが、それを保証するつもりはありません。

前の答えに基づいて、おそらく配列を使用して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

ただし、複数行の文字列では失敗するようです。

Bash配列の移植性がどの程度かはわかりません。上記のスニペットは&quot; GNU bash、バージョン3.2.17(1)-release(i386-apple-darwin9.0)&quot;

でテストされました

私のbashのみのソリューション:

TEMPLATE='
foo
$var1
bar
$var2'
eval "echo \"$TEMPLATE\""

まったく同じものを探していたため、この質問につまずいたばかりで、 envsubst(1)が見つかりました。

環境変数の使用を気にしない場合は、 envsubst を使用できます。

PLACEHOLDER_1='string 1' PLACEHOLDER_2='multiline 
string 
2' envsubst < output.template 

変数がたくさんある場合は、それらをファイルに保存して source するだけです(ソースファイルの最後で export を使用することを忘れないでください!)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top