使用sed修复git pre-commit钩子中的空格,我遇到了问题:
sed -i '' [the regex] [the file]
类似comments by others提到了这种不一致性,并且取出引号可以解决问题。这让我感到困惑,因为我认为sed -i应该在文件后面紧跟一个文件名作为参数。它可能是壳不一致;我链接的要点是.sh脚本,我使用bash / centos。
sed -i ''
用法背后的魔力/问题是什么?如何解析''
纠正问题?
答案 0 :(得分:1)
正如@avinashraj在他们的评论中提到的BSD sed
需要 -i
的参数,而GNU sed
使该参数成为可选的(并且不允许在CentOS 5上进行快速测试的空间。
由于使用GNU sed
的{{1}}行为将失败,因为它会假定sed -i '' 'script' file
没有参数,请使用-i
作为要运行的脚本,并使用{ {1}}作为第一个操作的文件。
使用''
将解决'script'
的脚本文件名问题,但会将sed -i '' -e 'script' file
解释为文件名。
使用GNU sed
解决 问题。
我不知道这对''
是否合法。我希望sed -i'' -e 'script' file
没问题。
问题是它是否接受了对 BSD sed
标志的后缀。
编辑:正如@CharlesDuffy准确地指出-e 'script'
不可能接受-i
或它也会接受BSD sed
,因为它无法区分其参数处理中的那些(空字符串已经在那一点上消失了。)
这意味着,除非我错过了某些内容或-i''
能够正确接受-i
,否则我无法通过便携式方式进行此操作。
答案 1 :(得分:0)
下面的函数定义了一个sed_inplace
命令,它试图在任何平台上做正确的事情。 (请注意,它需要bash
作为shell)。
sed_inplace() {
local -a args=( "$@" )
local sed_version
if sed_version=$(sed --version 2>&1) && [[ $sed_version = *'(GNU sed)'* ]]; then
# the GNU version
sed -i "$@"
elif [[ $sed_version = *"[-i "* ]]; then
# assuming this to be the BSD version with -i
sed -i '' "$@"
else
# the generic version
local file=${args[${#args[@]} - 1]}
local tempfile=$(mktemp "${file}.XXXXXX")
if sed "$@" <"$file" >"$tempfile"; then
mv "$tempfile" "$file"
else
local rc=$?
rm -f -- "$tempfile"
return $rc
fi
fi
}
当然,如果您没有尝试使用sed -i
,而是使用ex
,则可以避免这种混乱。