これは、VAR2に従って更新する必要があるテンプレート変数VAR1です。変数の順序は次のとおりです。 sedコマンドなしでVAR1を更新する方法は?
#!/bin/bash
VAR1="<tr>
<th>\$VAR2</th>
</tr>"
VAR2=test
echo $VAR2
答え1
あなたが使用できるenvsubst
:
(付属のPOSIXシェルを使用してくださいbash
):
VAR1="<tr>
<th>\$VAR2</th>
</tr>"
VAR2=test
expanded_VAR1=$(
export VAR2
printf '%s\n' "$VAR1" |
envsubst '$VAR2'
)
または、すべての単語拡張(パラメータ拡張、コマンド置換、算術拡張)を実行します。~上zsh
パラメータ拡張の場合は、対応するe
パラメータ拡張フラグを使用できます。
#!/bin/zsh -
VAR1="<tr>
<th>\$VAR2</th>
</tr>"
VAR2=test
expanded_VAR1=${(e)VAR1}
POSIXシェルでは、eval
here-documentを使用して同様の操作を実行できます。
VAR1="<tr>
<th>\$VAR2</th>
</tr>"
VAR2=test
expanded_VAR1=$(eval "cat << EOF
$VAR1
EOF")
bash
またはのもう1つのオプションは、次のものを使用することzsh
ですprintf
。
VAR1='<tr>
<th>%s</th>
</tr>'
VAR2=test
printf -v expanded_VAR1 -- "$VAR1" "$VAR2"
zsh
(使用しない)を使用すると、次の構文を使用してthパラメータを参照bash
できます%n$s
(多くの実装と同様)。printf(3)
n
#! /bin/zsh -
VAR1='<tr>
<th>%1$s</th> <th>%1$s again</th> <th>%2$s</th>
</tr>'
VAR2=test VAR3=test2
printf -v expanded_VAR1 -- "$VAR1" "$VAR2" "$VAR3"
または、名前付き形式ディレクティブを使用します(zformat
、、NUL、および10進数を除く単一バイト文字に制限されています)。-
.
#! /bin/zsh -
VAR1='<tr>
<th>%a</th> <th>%a again</th> <th>%b</th>
</tr>'
VAR2=test VAR3=test2
zformat -f expanded_VAR1 "$VAR1" "a:$VAR2" "b:$VAR3"
を使用すると、代わりにを使用してHTMLの特殊文字(beなど)を正しくエンコードできますが、ksh93
ASCII以外の文字の場合は、iso8859-1文字セットを使用するロケールでのみ正しく機能します。サポートされていませんが機能します。%H
%s
printf
&
&
ksh93
printf
-v
expanded_VAR1=${ printf... ;}
/メソッドを使用すると、printf
テンプレートのリテラル文字をzformat
エスケープできます(次のように)、/ +here-docメソッドを使用すると/ /プレフィックスを付けてエスケープできます。それからAFAIK、脱出口はありません。%
%%
\
\\
printf
e
eval
$
`
\
\
envsubst
$
答え2
パラメータ拡張を使用して、var1の一意の文字列をvar2の値に置き換えることができます。
var1='<tr>
<th>unique_placeholder_var2</th>
</tr>'
var2=test
echo "${var1/unique_placeholder_var2/"$var2"}"
答え3
var1
正しい形式のXMLが含まれているとします。
var1='
<tr>
<th>$var2</th>
</tr>
'
var2=test
xmlstarlet
その後、すべてのノードの値をth
次のようにシェル変数の値としてリテラル値に置き換えることができます。$var2
var2
var1=$( printf '%s\n' "$var1" | xmlstarlet ed -u '//th[text() = "$var2"]' -v "$var2" )
これは、変更するすべてのノードを xmlstarlet
選択するためにXPATHクエリを呼び出します。このノードの値はシェル変数の値に置き換えられ、結果は標準出力に書き込まれます。th
xmlstarlet
var2
$ printf '%s\n' "$var1"
<?xml version="1.0"?>
<tr>
<th>test</th>
</tr>
これは、var2
XML文書に含める値を正しくエンコードします。
$ var1='
<tr>
<th>$var2</th>
</tr>
'
$ var2='HÉLLO :->'
$ var1=$( printf '%s\n' "$var1" | xmlstarlet ed -u '//th[text() = "$var2"]' -v "$var2" )
$ printf '%s\n' "$var1"
<?xml version="1.0"?>
<tr>
<th>HÉLLO :-></th>
</tr>
答え4
テンプレート内の変数を置き換える一般的な方法:
- bash正規表現を使用して変数名をキャプチャします(欲張り一致のため、ここでは変数名が右から左に一致します)。
- 変数を使用して間接的に変数値を取得する
- 無限ループを回避するには、入力文字列から一致するvarnameを削除します(これを行うと元の文字列が破損するため、必要に応じてバックアップしてください)。
デモ
置き換えるテンプレートと(すべてではない)変数を設定します。
VAR1="<tr> <th>\$VAR2</th> <th>\$VAR3</th> </tr>" VAR2=test unset VAR3
交換の実行
result="" while [[ $VAR1 =~ (.*)\$([[:alpha:]_][[:alnum:]_]*)(.*) ]]; do varname=${BASH_REMATCH[2]} [[ -v $varname ]] && replacement=${!varname} || replacement="\$${varname}" result="${replacement}${BASH_REMATCH[3]}${result}" VAR1=${BASH_REMATCH[1]} done result="${VAR1}${result}" declare -p result
検査結果
declare -- result="<tr> <th>test</th> <th>\$VAR3</th> </tr>"
これを行うには、-v
オペレータはbashバージョン4.3+を使用する必要があります。