いくつかの環境変数があります。動的に変換したい値が複数あります。
環境変数:printenv | grep proj_env_repo
を使用してこの環境変数を取得しています(printenv | grep $value
のように動作します)。
値はproj_env_repo
です
そして私の結果は
proj_env_repo_db_username=username
TF_ENV_db_username=username
に変換したい
誰かが私を助けてくれますか? bashスクリプトで関数を探しています。
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
に格納されている変数の値を使用して取得されています。
元の変数をさらに設定解除するには、export
の後、ループの終了前にunset "$variable"
を使用します。
トレースをオンにしてこれをテストして実行します。
$ 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
古い名前の接頭辞を1番目の引数として、新しい接頭辞を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
は構文${!$1@}
をサポートしていないため、ここではループでbash
を使用しています。関数は、$1
および$2
(関数に指定された1番目と2番目の引数)の値に従って変数の名前を変更するための適切なシェルコードを(文字列として)構築し、eval
このシェルコードを実行します。
この関数は次のように使用します
rename_var project_env_repo TF_ENV
...または、変数を使用して、
rename_var "$old_variable_prefix" "$new_variable_prefix"
注:(ユーザー入力でeval
を使用して)このようなことを行う場合、評価するコードが有効であることをテストする必要がありますそれがあなたがそれであるとあなたが期待するものであるということ。この場合、これは、$1
および$2
を有効な変数名のプレフィックスとして検証することを意味します。そうでない場合、少なくとも引用符と}
はeval
で構文エラーを引き起こし、コマンドインジェクションの可能性があります。
注:これは私がこれまでに使用したことが初めて(私が思う) eval
を使用した 。ただし、上記のコードを使用する必要はありませんが、質問の背景知識がわからないため、質問に対する批判ではありません(それ自体が興味深い質問です)。
関連(ソフトウェアエンジニアリングサイト):
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
-=記号を使用して、入力行をコンポーネントパーツに分割します。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
は、proj_env_repo
の最初のインスタンスをTF_ENV
で変換します。
TF_ENV_db_username=$proj_env_repo_db_username
eval
はそのステートメントを評価します。
unset
は、古い変数が削除されることを確認します。