sed 正则表达式在 shell 脚本中不起作用

sed 正则表达式在 shell 脚本中不起作用

鉴于:

~$ 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

相关内容