[解決済み] Bash Templating。Bashでテンプレートから設定ファイルを作るには?
質問
自分のウェブサーバー用に、ApacheとPHPの設定ファイルを自動作成するスクリプトを書いています。CPanelやISPConfigのようなGUIは使いたくありません。
私は、ApacheとPHPの設定ファイルのいくつかのテンプレートを持っています。Bashスクリプトは、テンプレートを読み、変数の置換を行い、解析されたテンプレートをいくつかのフォルダに出力する必要があります。それを行うための最良の方法は何ですか?私はいくつかの方法を考えることができます。どれがベストですか、またはそれを行うにはいくつかのより良い方法があるかもしれませんか?私は純粋なBashでそれをしたいです(例えばPHPでは簡単です)。
1) テキストファイルの${}プレースホルダーを置換する方法は?
template.txtを使用します。
the number is ${i}
the word is ${word}
script.shを使用します。
#!/bin/sh
#set variables
i=1
word="dog"
#read in template one line at the time, and replace variables
#(more natural (and efficient) way, thanks to Jonathan Leffler)
while read line
do
eval echo "$line"
done < "./template.txt"
ところで、ここで出力を外部ファイルにリダイレクトするにはどうしたらいいのでしょうか?変数に引用符などが含まれている場合、何かエスケープする必要があるのでしょうか?
2) cat & sed を使って、各変数をその値に置き換える。
与えられたtemplate.txt。
The number is ${i}
The word is ${word}
コマンドです。
cat template.txt | sed -e "s/\${i}/1/" | sed -e "s/\${word}/dog/"
多くのシンボルをエスケープする必要があり、また多くの変数を使用すると行が長くなりすぎるため、私には悪いように思えます。
他にエレガントで安全な解決策はないのでしょうか?
どのように解決するのですか?
これを使うことができます。
perl -p -i -e 's/\$\{([^}]+)\}/defined $ENV{$1} ? $ENV{$1} : $&/eg' < template.txt
をすべて置き換えるために
${...}
の文字列を、対応する環境変数に置き換えてください(このスクリプトを実行する前に、環境変数をエクスポートすることを忘れないでください)。
純粋なbashの場合、これは動作するはずです(変数に${...}文字列が含まれないと仮定しています)。
#!/bin/bash
while read -r line ; do
while [[ "$line" =~ (\$\{[a-zA-Z_][a-zA-Z_0-9]*\}) ]] ; do
LHS=${BASH_REMATCH[1]}
RHS="$(eval echo "\"$LHS\"")"
line=${line//$LHS/$RHS}
done
echo "$line"
done
. RHSが自分自身を参照する変数を参照してもハングしない解決策。
#!/bin/bash
line="$(cat; echo -n a)"
end_offset=${#line}
while [[ "${line:0:$end_offset}" =~ (.*)(\$\{([a-zA-Z_][a-zA-Z_0-9]*)\})(.*) ]] ; do
PRE="${BASH_REMATCH[1]}"
POST="${BASH_REMATCH[4]}${line:$end_offset:${#line}}"
VARNAME="${BASH_REMATCH[3]}"
eval 'VARVAL="$'$VARNAME'"'
line="$PRE$VARVAL$POST"
end_offset=${#PRE}
done
echo -n "${line:0:-1}"
警告 : bashでNULを含む入力を正しく処理する方法、あるいは末尾の改行量を保持する方法を知りません。最後のバリエーションは、シェルがバイナリ入力を「愛する」ために、そのまま提示されます。
-
read
はバックスラッシュを解釈します。 -
read -r
はバックスラッシュを解釈しませんが、最終行が改行で終わっていない場合は削除されます。 -
"$(…)"
は末尾の改行を存在する数だけ取り除くので、私は…
で; echo -n a
を使用しecho -n "${line:0:-1}"
: これは最後の文字を削除します (これはa
を含む)、入力と同じ数の末尾の改行を保持します。
関連
-
[解決済み] Bashスクリプトのソースディレクトリをスクリプト自体から取得するにはどうすればよいですか?
-
[解決済み] Bashシェルスクリプトでディレクトリが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで通常のファイルが存在しないかどうかを判断する方法を教えてください。
-
[解決済み] Bashで文字列変数を連結する方法
-
[解決済み] Bashで文字列が部分文字列を含むかどうかをチェックする方法
-
[解決済み] Bashスクリプトからプログラムが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで文字列をデリミターで分割するには?
-
[解決済み] Bashでコマンドライン引数を解析するには?
-
[解決済み] Bashでコマンドの出力に変数を設定するにはどうすればよいですか?
-
[解決済み] Bashで変数が設定されているかどうかを確認する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】シェルスクリプトで整数式が期待されるエラーが発生する
-
[解決済み】firebase-tools "-bash: firebase: command not found".
-
[解決済み] bash スクリプトを実行しているドッカーエントリーポイントが "パーミッション拒否" になる
-
[解決済み] bashで::演算子は何をするのですか?
-
[解決済み] grepの出力に含まれる重複を削除する
-
[解決済み] AWS CLIのプロファイルを一時的に切り替えるには?
-
[解決済み] Bashスクリプトのset -o pipefailの意味を教えてください。
-
[解決済み] Bashのforeachループ
-
[解決済み】シェル変数に引用符で囲むのはいつ?
-
[解決済み】テキストファイルの${}プレースホルダーを置換する方法は?