如何用sed将JSON占位符捕获组替换为对应环境变量(Alpine容器)
问题场景
假设我们有如下内容的source_file.json:
{ "someVar": "__SOME_ENV_VAR__", "anotherVar": "__ANOTHER_ENV_VAR__", "yetAnotherVar": "__ONE_MORE_ENV_VAR__" }
需求
需要实现以下操作:
- 使用模式
__([A-Z_]+)__搜索环境变量占位符 - 将捕获组
([A-Z_]+)(即\1)对应到同名环境变量(如SOME_ENV_VAR、ANOTHER_ENV_VAR、ONE_MORE_ENV_VAR)的值 - 用对应环境变量的值替换该捕获组
尝试过的方法(均失败)
方法1:用sed一次性完成搜索替换
sed -i "s/__([A-Z_]\+)__/${\1}/g" source_file.json
方法2:逐个替换所有环境变量实例
env | while IFS='=' read -r key value; do sed -i "s/__$key__/$value/g" done
两种方法要么报错,要么无法正确插值环境变量,输出类似"someVar": "$SOME_ENV_VAR"的结果。相关技术文章大多仅覆盖提前已知具体环境变量的场景,未涉及捕获组插值的情况。
注意: 需将实现写入/bin/sh脚本,在基于Alpine的Docker容器中执行,因此不考虑安装gettext包使用
envsubst的方案
解决方案
方案1:用awk实现动态替换
awk可直接读取环境变量,支持正则捕获与动态取值,适配场景需求:
awk '{ while(match($0, /__([A-Z_]+)__/, arr)) { env_var = arr[1] if (ENVIRON[env_var] != "") { gsub(/__'"$env_var"'__/, ENVIRON[env_var]) } } print $0 }' source_file.json > temp.json && mv temp.json source_file.json
说明:
match($0, /__([A-Z_]+)__/, arr)匹配占位符并将捕获的环境变量名存入数组arrENVIRON[env_var]直接获取对应环境变量的值- 通过临时文件实现原地修改(awk无直接原地修改参数)
方案2:改进sed循环替换方法
修正原方法2的文件指定问题,同时过滤不符合格式的环境变量:
for key in $(printenv | grep -E '^[A-Z_]+=' | cut -d'=' -f1); do value=$(printenv "$key") sed -i "s/__${key}__/${value}/g" source_file.json done
说明:
grep -E '^[A-Z_]+='过滤出仅含大写字母与下划线的环境变量- 循环遍历符合要求的变量,逐个替换对应占位符
验证示例
若已设置环境变量:
export SOME_ENV_VAR="foo" export ANOTHER_ENV_VAR="bar" export ONE_MORE_ENV_VAR="baz"
执行任一方案后,source_file.json会更新为:
{ "someVar": "foo", "anotherVar": "bar", "yetAnotherVar": "baz" }
内容的提问来源于stack exchange,提问作者S. Rullio
相关产品推荐
相关产品推荐

