我正在开发部署脚本,我的需要是替换配置文件中的数据库(或其他系统)凭据。
我有带有如下凭据的 PHP 文件:
<?php
return [
'mysql-rw' => [
'dns' => 'mysql-rw.local',
'user' => 'local',
'password' => 'PASS__LABELONE__',
],
'mysql-ro' => [
'dns' => 'mysql-ro.local',
'user' => 'local',
'password' => 'PASS__LABELTWO__',
],
];
我还在 CI 服务器中设置了 Bash 环境变量 -LABELONE
和LABELTWO
.我想用一行sed
命令替换文件中的模板,但有错误或替换错误:
LABELONE=pass1 LABELTWO=pass2 sed -r "s/PASS__(.+)__/${!\1}/" tst.txt
bash: s/PASS__(.+)__/${!\1}/: bad substitution
我的方法是:
- 在文件中查找模板
- 从中捕获标签(在 PASS__LBL__ 中它是 LBL)
- 将模板替换为 env。变量($LBL)
我怎样才能评估这样的动态变量,sed
或者它是不真实的?
答案1
Perl 可以通过 %ENV 哈希访问 env 变量:
LABELONE=pass1 LABELTWO=pass2 perl -pe 's/PASS__(.+)__/$ENV{$1}/' -- tst.txt
答案2
(...)
从表达式捕获的组的值sed
无法动态处理巴什环境变量,使用GNUawk
改为程序:
export LABELONE="pass1"
export LABELTWO="pass2"
awk 'match($0, /PASS__([^_]+)__/, m){ sub(/PASS__[^_]+__/, ENVIRON[m[1]]) }1' testfile
输出:
<?php
return [
'mysql-rw' => [
'dns' => 'mysql-rw.local',
'user' => 'local',
'password' => 'pass1',
],
'mysql-ro' => [
'dns' => 'mysql-ro.local',
'user' => 'local',
'password' => 'pass2',
],
];
ENVIRON
包含环境值的关联数组。数组索引是环境变量名称;元素是特定环境变量的值。
答案3
可能不是您正在寻找的,但是如果您通过多个 sed 顺序通过管道传递它,并显式匹配标签,它确实可以工作......当然不优雅。
LABELONE=pass1; LABELTWO=pass2;
sed -r "s/PASS__LABELONE__/$LABELONE/" tst.txt | sed -r "s/PASS__LABELTWO__/$LABELTWO/"
当然,如果您有更多变量或者它们被命名为其他名称,这很快就会变得乏味。你可能可以在 bash 本身中做一些事情,但不幸的是,我自己不知道如何在一行 sed 中做到这一点。
编辑:好吧,假设这些变量确实是环境变量并且您可以访问 envsubst,那么这是可行的
导出 LABLEONE=pass1
导出 LABELTWO=pass2
sed -r "s/PASS__(.+)__/$\1/g" test.txt | sed -r "s/PASS__(.+)__/$\1/g" test.txt |环境替换
然而,它依赖于 envsubst,我认为这是 gettext 的一部分。那么不知道这是否适合你?另外,通过在配置文件中写入实际的 $LABELONE 变量,您可以完全摆脱 sed 并只使用 envsubst。就我个人而言,我喜欢另一条评论中提到的 perl 脚本,所以我投了赞成票。