環境変数があります。これらの値を複数の動的に変換したいと思います。
printenv | grep proj_env_repo
環境変数:(like this)を使用してこの環境変数を取得しますprintenv | grep $value
。
したがって、値はproj_env_repo
私の結果は
proj_env_repo_db_username=username
に変換したいです。TF_ENV_db_username=username
誰でも私を助けることができますか? Bashスクリプトで関数を探しています。
答え1
以下では、変数名の接頭辞の一致と変数間接の使用を使用しますbash
。
proj_env_repo_db_username=username
proj_env_repo_db_host=host
proj_env_repo_db_port=port
for variable in "${!proj_env_repo@}"; do
export "TF_ENV${variable#proj_env_repo}"="${!variable}"
done
"${!proj_env_repo@}"
このループは、名前プレフィックスを共有する変数名のリストを生成するために使用されますproj_env_repo
。各反復には、$variable
これらの変数の1つの名前が表示されます。
ループ内では、export
プレフィックスを削除して文字列に置き換えてproj_env_repo
新しい環境変数を作成するために使用されますTF_ENV
。新しい環境変数の値は、変数間接参照、${!variable}
つまり名前が格納されている変数の値を使用して取得されます$variable
。
元の変数をさらに設定解除するには、ループが終了する前にafterを使用してくださいunset "$variable"
。export
トレースをオンにしてテストを実行してみてください。
$ bash -x script.sh
+ proj_env_repo_db_username=username
+ proj_env_repo_db_host=host
+ proj_env_repo_db_port=port
+ for variable in "${!proj_env_repo@}"
+ export TF_ENV_db_host=host
+ TF_ENV_db_host=host
+ for variable in "${!proj_env_repo@}"
+ export TF_ENV_db_port=port
+ TF_ENV_db_port=port
+ for variable in "${!proj_env_repo@}"
+ export TF_ENV_db_username=username
+ TF_ENV_db_username=username
関数として、古い名前のプレフィックスを最初の引数として取り、新しいプレフィックスを2番目の引数として使用します。
rename_var () {
# Make sure arguments are valid as variable name prefixes
if ! [[ $1 =~ ^[a-zA-Z_][a-zA-Z_0-9]*$ ]] ||
! [[ $2 =~ ^[a-zA-Z_][a-zA-Z_0-9]*$ ]]
then
echo 'bad variable name prefix' >&2
return 1
fi
eval 'for variable in "${!'"$1"'@}"; do
export "'"$2"'${variable#'"$1"'}"="${!variable}"
done'
}
構文はサポートされていないため、ここではオーバーループを使用しますeval
。この関数は、(関数の最初と2番目のパラメータで指定されている)値に基づいて変数の名前を変更するための適切なシェルコード(文字列)を設定し、このシェルコードを実行するために使用されます。bash
${!$1@}
$1
$2
eval
この機能は次のように使用できます。
rename_var project_env_repo TF_ENV
...または変数を使用して
rename_var "$old_variable_prefix" "$new_variable_prefix"
注:このような操作を実行するとき(eval
ユーザー入力を使用して)〜しなければならない評価したコードが機能し、期待どおりに機能するかどうかをテストします。この場合、これは有効な変数名プレフィックスで検証する$1
ことを意味します。$2
そうしないと、少なくとも引用符を使用すると}
構文エラーが発生し、eval
コマンドが挿入される可能性があります。
注:今回が初めてです(私の考えでは)持つ使用eval
。私は上記のコードを使用しなければならない場所には決して置かないでしょうが、明らかにこの質問の裏話を知らないので、これは実際に質問に対する批判ではありません(それ自体は興味深い質問です)。
関連(ソフトウェアエンジニアリングウェブサイト):
答え2
while IFS='=' read -r name value; do
new_name="TF_ENV${name#proj_env_repo}"
export "$new_name=$value"
unset "$name"
done < <( printenv | grep proj_env_repo )
秘密の材料は次のとおりです。
- シェルパラメータ拡張
IFS='=' read -r name value
-- = 記号を使用して受信ラインをコンポーネント部分に分割します。- 使うプロセスの交換したがって、whileループは現在のシェルで実行されます。
答え3
for v in `printenv | grep proj_env_repo`
do
eval `echo "$v=\$$v" | sed -e 's/proj_env_repo/TF_ENV/'`
unset $v
done
プリントecho
:
proj_env_repo_db_username=$proj_env_repo_db_username
sed
withの最初のインスタンスを変換します。proj_env_repo
TF_ENV
TF_ENV_db_username=$proj_env_repo_db_username
eval
声明を評価してください。
unset
古い変数が削除されていることを確認してください。