我有一些环境变量。我想动态转换多个这样的值。
printenv | grep proj_env_repo
环境变量:我使用(像这样)获取这个环境变量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
都会出现这些变量之一的名称。
在循环内部,export
用于通过删除前缀proj_env_repo
并将其替换为字符串来创建新的环境变量TF_ENV
。新环境变量的值是使用变量间接寻址获得的${!variable}
,即名称存储在 中的变量的值$variable
。
要另外取消设置原始变量,请在循环结束之前使用unset "$variable"
after , 。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
作为一个函数,将旧名称前缀作为其第一个参数,将新前缀作为其第二个参数:
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
over 循环。该函数构造适当的 shell 代码(作为字符串),用于根据和的值(赋予函数的第一个和第二个参数)重命名变量,然后用于执行此 shell 代码。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
答案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
转换withsed
的第一个实例。proj_env_repo
TF_ENV
TF_ENV_db_username=$proj_env_repo_db_username
评估eval
该陈述。
确保unset
旧变量被删除。