使用 sed 命令参数与 GNU 和 BSD Unix 兼容(就地编辑)

使用 sed 命令参数与 GNU 和 BSD Unix 兼容(就地编辑)

我有一个 shell 脚本,目前用于移动应用程序的一些构建相关内容。

由于 BSD 和 GNU 之间的细微差别,最初在 Mac (BSD) 上编写的构建脚本之一

environment=$1

if [[ -z $environment ]]; then 
  environment="beta"
fi
if ! [[ $environment =~ (live|beta) ]]; then
  echo "Invalid environment: $environment"
  exit 1
fi

mobile_app_api_url="https://api"$environment".mysite.com"

cp app/index.html.mob MobileApp/www/index.html

sed -i'' "s#MOBILE_APP_API_URL#\"$mobile_app_api_url\"#g" MobileApp/www/index.html

sed 命令是在 BSD (Mac) 上编写的,但由于构建可能在 Mac 或 Ubuntu (GNU) 上进行,我需要修改它以在两种风格上使用,最好的方法是什么?

答案1

-i这样做是为了规避以下标志的可移植性问题sed

sed 'sed-editing-commands' thefile >tmpfile && mv tmpfile thefile

sed即,写入临时文件,然后如果命令没有失败,则用临时文件替换输入文件。

这可以移植到sed我所知道的所有实现中。

要安全地创建临时文件名,请使用mktemp.虽然这不是一个标准实用程序,但它可以在我有权访问的所有 Unices 上使用(OpenBSD、NetBSD、Solaris、macOS、Linux):

tmpfile=$(mktemp)
sed 'sed-editing-commands' thefile >"$tmpfile" && mv "$tmpfile" thefile

答案2

您需要意识到 不应$mobile_app_api_url包含对 s/// 的 RHS 上的 sed 有意义的字符。具体来说,您需要确保此变量已正确转义以下内容: & # \ newline即在插入之前。

答案3

代替:

cp app/index.html.mob MobileApp/www/index.html
sed -i'' "s#MOBILE_APP_API_URL#\"$mobile_app_api_url\"#g" MobileApp/www/index.html

做就是了:

sed "s#MOBILE_APP_API_URL#\"$mobile_app_api_url\"#g" \
  < app/index.html.mob >  MobileApp/www/index.html

您还可以通过将顶部部分更改为以下内容来删除对ksh93/的依赖:bash

environment=$1

case $environment in
  "") environment=beta;;
  live|beta) ;;
  *)
    printf >&2 'Invalid environment: "%s"\n' "$environment"
    exit 1;;
esac

也可以看看environment=${1:-beta}

[[ $environment =~ (live|beta) ]]顺便说一句,ksh93bash测试是否$environment 包含 live或者beta这听起来不像你想要的。你需要[[ $environment =~ ^(live|beta)$ ]]测试一下是否可以 live或者beta

相关内容