在Linux和Mac上是否都可以调用sed在没有备份的情况下进行就地编辑?虽然OS X附带的BSD sed似乎需要sed -i "…,但GNU sed Linux发行版通常会将引号解释为空的输入文件名(而不是备份扩展名),并且需要sed -i…。
是否有适用于这两种风格的命令行语法,以便我可以在两个系统上使用相同的脚本?
在Linux和Mac上是否都可以调用sed在没有备份的情况下进行就地编辑?虽然OS X附带的BSD sed似乎需要sed -i "…,但GNU sed Linux发行版通常会将引号解释为空的输入文件名(而不是备份扩展名),并且需要sed -i…。
是否有适用于这两种风格的命令行语法,以便我可以在两个系统上使用相同的脚本?
当前回答
我遇到了这个问题。唯一快速的解决方案是将mac中的sed替换为gnu版本:
brew install gnu-sed
其他回答
正如Noufal Ibrahim所问的,为什么不能使用Perl?任何Mac都会有Perl,而且很少有Linux或BSD发行版在基本系统中不包含某些版本的Perl。BusyBox是唯一可能缺少Perl的环境之一(对于-i,它的工作方式与GNU/Linux类似,只是不能指定备份扩展)。
正如ismail所建议的,
由于perl在任何地方都可用,我只是做perl -pi -e s,foo,bar,g target.file
在处理sed -i在GNU/Linux和BSD/Mac之间根本不兼容的问题时,这似乎是一个比脚本、别名或其他变通方法更好的解决方案。
适用于GNU系统和OSX的可移植脚本:
if [[ $(uname) == "Darwin" ]]; then
SP=" " # Needed for portability with sed
fi
sed -i${SP}'' -e "s/foo/bar/g" -e "s/ping/pong/g" foobar.txt
下面是另一个在Linux和macOS上工作的版本,无需使用eval,也无需删除备份文件。它使用Bash数组来存储sed参数,这比使用eval更简洁:
# Default case for Linux sed, just use "-i"
sedi=(-i)
case "$(uname)" in
# For macOS, use two parameters
Darwin*) sedi=(-i "")
esac
# Expand the parameters in the actual call to "sed"
sed "${sedi[@]}" -e 's/foo/bar/' target.file
这不会创建备份文件,也不会创建带有追加引号的文件。
没有办法让它正常工作。
一种方法是使用临时文件,比如:
TMP_FILE=`mktemp /tmp/config.XXXXXXXXXX`
sed -e "s/abc/def/" some/file > $TMP_FILE
mv $TMP_FILE some/file
这对两者都有效
我遇到了这个问题。唯一快速的解决方案是将mac中的sed替换为gnu版本:
brew install gnu-sed