因此 sed 的行为会有所不同,具体取决于它是 OSX/BSD 还是 GNU 版本。
OSX 需要
sed -i '' <pattern> <file>
而这适用于 GNU sed:
sed -i <pattern> <file>
所以我有这个:
darwin=false;
case "$(uname)" in
Darwin*) darwin=true ;;
esac
if $darwin; then
sedi="sed -i '' "
else
sedi="sed -i"
fi
然后我尝试在 OSX 上调用它
$sedi "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.java
除了创建一个名为“Version.java”的备份文件外,它还能正常工作。
我不确定为什么这不起作用,因为如果我从 CLI 显式执行此操作:
sed -i '' "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.java
它无需创建备份文件即可工作。
有什么想法吗?
答案1
当您扩展sedi
变量时,发生的情况是 被作为参数''
传递,而不是按预期创建一个空参数。sed
我能看到的最好的方法是让你的sedi
变量成为一个数组:
if $darwin; then
sedi=(sed -i '')
else
sedi=(sed -i)
fi
并像这样使用:
"${sedi[@]}" "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.java
否则,我认为将您的参数变成实际的空参数的唯一方法是与您的原始声明一起''
使用:eval
eval $sedi '"s/VERSION =.*;/VERSION = \"${lver}\";/g"' Version.java
然而,这是一个有点令人讨厌的解决方案,因为您必须在命令的其余部分添加额外的引号/转义层。此外,eval
尽可能避免使用通常是良好(且安全)的做法。
更新
如下所述,创建一个函数就可以了。在同一轨道上, analias
可能是最短的方法:
if $darwin; then
alias sedi="sed -i ''"
else
alias sedi="sed -i"
fi
使用法简单:
sedi "s/VERSION =.*;/VERSION = \"${lver}\";/g" Version.java
答案2
定义一个换行的 shell 函数sed
:
case "$(uname)" in
Darwin*) sed () { command sed -i '' "$@"; } ;;
*) sed () { command sed -i "$@"; } ;;
esac