展開スクリプトを開発しており、構成ファイル内のデータベース(または他のシステム)資格情報を置き換える必要があります。
次の資格情報を含むPHPファイルがあります。
<?php
return [
'mysql-rw' => [
'dns' => 'mysql-rw.local',
'user' => 'local',
'password' => 'PASS__LABELONE__',
],
'mysql-ro' => [
'dns' => 'mysql-ro.local',
'user' => 'local',
'password' => 'PASS__LABELTWO__',
],
];
LABELONE
また、CIサーバーにBash環境変数が設定されています。ファイルのテンプレートを1行のコマンドに置き換えたいLABELTWO
のですが、エラーまたは代替エラーがあります。sed
LABELONE=pass1 LABELTWO=pass2 sed -r "s/PASS__(.+)__/${!\1}/" tst.txt
bash: s/PASS__(.+)__/${!\1}/: bad substitution
私のアプローチは次のとおりです。
- ファイル内のテンプレートを探す
- タグをキャプチャします(PASS__LBL__ではLBLです)。
- テンプレートをenvに置き換えます。変数($ LBL)
そのような動的変数をどのように評価できますかsed
?それとも非現実的なものですか?
答え1
Perlは%ENVハッシュを介してenv変数にアクセスできます。
LABELONE=pass1 LABELTWO=pass2 perl -pe 's/PASS__(.+)__/$ENV{$1}/' -- tst.txt
答え2
(...)
式でキャプチャされたグループの値はsed
動的に処理できません。強く打つGNUを使用する環境変数awk
プログラムに変更:
export LABELONE="pass1"
export LABELTWO="pass2"
awk 'match($0, /PASS__([^_]+)__/, m){ sub(/PASS__[^_]+__/, ENVIRON[m[1]]) }1' testfile
出力:
<?php
return [
'mysql-rw' => [
'dns' => 'mysql-rw.local',
'user' => 'local',
'password' => 'pass1',
],
'mysql-ro' => [
'dns' => 'mysql-ro.local',
'user' => 'local',
'password' => 'pass2',
],
];
ENVIRON
環境値を含む連想配列。配列インデックスは環境変数名、要素は特定の環境変数の値です。
答え3
おそらくあなたが探しているものではないかもしれませんが、複数のsedを順番にパイプしてタグを明示的に一致させると機能します...確かにエレガントではありません。
LABELONE=pass1; LABELTWO=pass2;
sed -r "s/PASS__LABELONE__/$LABELONE/" tst.txt | sed -r "s/PASS__LABELTWO__/$LABELTWO/"
もちろん、変数が多い場合や別の名前で指定された場合は、すぐに退屈になる可能性があります。おそらくbash自体で何かをすることができます。しかし、残念ながら私はsedの1行でそれを行う方法を知りません。
編集:まあ、これらの変数が実際には環境変数であり、envsubstにアクセスできると仮定すると機能します。
エクスポートLABLEONE=pass1
エクスポートLABELTWO=pass2
sed -r "s/PASS__(.+)__/$\1/g" test.txt | sed -r "s/PASS__(.+)__/$\1/g" test.txt |環境の交換
しかし、これはgettextの一部であるenvsubstに依存します。これがあなたに適しているかどうかはわかりませんか?あるいは、sedを完全に削除し、構成ファイルに実際の$ LABELONE変数を作成してenvsubstを使用することもできます。個人的には、他のコメントに記載されているperlスクリプトが気に入って投票しました。