鉴于:
~$ cat .test-profile
export [email protected]
export MONGODB_URI='mongodb+srv://administrator:[email protected]/test?retryWrites=true&w=majority'
我编写了以下 shell 脚本来替换变量值:
BASH_PROFILE="$HOME/.test-profile"
MONGODB_URI="mongodb+srv://administrator:[email protected]/mysite_development?retryWrites=true&w=majority"
INSERT_ENV_VAR () {
if [[ -z "$2" ]]
then
echo "Failed to retrieve $1"
else
if grep -q "$1" "$BASH_PROFILE"; then
# Cannot use / delimiter, for value can contain /
sed -in -E "s|(export $1=)[a-zA-Z0-9@.:\/=&\-\?\+]+|\1$2|g" "$BASH_PROFILE"
else
echo "export $1=$2" >> "$BASH_PROFILE"
fi
fi
}
INSERT_ENV_VAR 'ADMIN_EMAIL' '[email protected]'
INSERT_ENV_VAR 'MONGODB_URI' $MONGODB_URI
虽然 ADMIN_EMAIL 变量被替换得很好,但 MONGODB_URI 变量没有被替换。我相信它必须与正则表达式内部的字符类 [] 做一些事情。但我不确定是什么。我用 ruby 这样的编程语言尝试过,它找到了匹配的结果。但使用 sed 它找不到匹配项。为什么?
这就是我期望.test-profile
之后的样子:
export [email protected]
export MONGODB_URI='mongodb+srv://administrator:[email protected]/mysite_development?retryWrites=true&w=majority'
注意“mysite_development”替换了“test”。
答案1
转义脚本中 MONGODB_URI 定义中的 & 符号并简化正则表达式,去掉sed 中-n
不必要的内容g
,我们最终得到这个(测试配置文件在这个版本中的命名不同,但应该是明确要做什么):
BASH_PROFILE="/tmp/test_profile"
MONGODB_URI="mongodb+srv://administrator:[email protected]/mysite_development?retryWrites=true\&w=majority"
INSERT_ENV_VAR () {
if [[ -z "$2" ]]
then
echo "Failed to retrieve $1"
else
if grep -q "$1" "$BASH_PROFILE"; then
# Cannot use / delimiter, for value can contain /
sed -i -E "s;(export $1=).*;\1$2;" "$BASH_PROFILE"
else
echo "export $1=$2" >> "$BASH_PROFILE"
fi
fi
}
INSERT_ENV_VAR 'ADMIN_EMAIL' '[email protected]'
INSERT_ENV_VAR 'MONGODB_URI' $MONGODB_URI
并使用测试配置文件运行它,我得到:
export [email protected]
export MONGODB_URI=mongodb+srv://administrator:[email protected]/mysite_development?retryWrites=true&w=majority
答案2
sed -i "/export $1=/{i export $1='$2'
;d}" "$BASH_PROFILE"
这将允许您使用sed
而无需&
替换\&
grep -q
可以有选择-F
,也可以-m 1