通过更改变量名称前缀重命名环境变量

Swa*_*wat 4 bash sed shell-script environment-variables

我有一些环境变量。我想动态转换多个这样的值。

环境变量:我正在使用printenv | grep proj_env_repo(这样做printenv | grep $value)来获取这个环境变量。

所以价值是 proj_env_repo

我的结果是

proj_env_repo_db_username=username
Run Code Online (Sandbox Code Playgroud)

我想把它转换成 TF_ENV_db_username=username

有人可以帮我吗?我正在寻找 bash 脚本中的函数。

Kus*_*nda 8

在 中使用变量名前缀匹配和变量间接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
Run Code Online (Sandbox Code Playgroud)

该循环用于"${!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
Run Code Online (Sandbox Code Playgroud)

作为将旧名称前缀作为其第一个参数和新前缀作为其第二个参数的函数:

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'
}
Run Code Online (Sandbox Code Playgroud)

我们eval在这里使用over 循环,因为bash不支持语法${!$1@}。该函数根据$1and的值$2(赋予函数的第一个和第二个参数)构造适当的 shell 代码(作为字符串)来重命名变量,然后使用它eval来执行此 shell 代码。

您可以将此功能用作

rename_var project_env_repo TF_ENV
Run Code Online (Sandbox Code Playgroud)

...或者,使用变量,

rename_var "$old_variable_prefix" "$new_variable_prefix"
Run Code Online (Sandbox Code Playgroud)

注意:在执行此类操作时(eval在用户输入上使用),您必须测试您评估的代码是否有效以及它是否符合您的预期。在这种情况下,这意味着验证$1$2作为有效的变量名称前缀。否则至少}会引起引号和 . 中的语法错误eval,并且存在命令注入的可能性。


注意:这是我第一次(我认为)不得不使用eval. 我永远不会让自己处于不得不使用上述代码的位置,但显然我不知道这个问题的背景故事,所以这并不是对这个问题的真正批评(这本身就是一个有趣的问题)。

相关(在软件工程网站上):