![使用 sed 命令参数与 GNU 和 BSD Unix 兼容(就地编辑)](https://linux22.com/image/106796/%E4%BD%BF%E7%94%A8%20sed%20%E5%91%BD%E4%BB%A4%E5%8F%82%E6%95%B0%E4%B8%8E%20GNU%20%E5%92%8C%20BSD%20Unix%20%E5%85%BC%E5%AE%B9%EF%BC%88%E5%B0%B1%E5%9C%B0%E7%BC%96%E8%BE%91%EF%BC%89.png)
我有一个 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) ]]
顺便说一句,ksh93
并bash
测试是否$environment
包含 live
或者beta
这听起来不像你想要的。你需要[[ $environment =~ ^(live|beta)$ ]]
测试一下是否可以是 live
或者beta
。