我在git
周围有一点find-replace实用程序。让我们忽略对不同方法ATM的建议。我真的想从sed
了解这个错误。看看命令
function git_find_replace
{
local grepexp="$1"
local replace="$2"
# build sed command
local sedcmd="s/$grepexp/$replace/g"
# First find the files; then pipe through xargs sed for replacement
git grep --name-only "$grepexp" | xargs sed -r "$sedcmd" -i ''
}
该命令有效,并且我得到了预期的结果,但是,当我在我的某个存储库上运行它时,我收到来自sed
的错误
sed: can't read : No such file or directory
但是git
组件返回一组全部存在的文件(为了帖子而略有损坏)
git grep --name-only 0.46.1
release/a.html
release/resources/javascript/a.js
release/resources/version
release/index.html
release/installer.html
我已使用ls
手动验证了这些文件的存在。例如,如果我将xargs
组件更改为此
git grep --name-only 0.46.1 | xargs ls -l
ls
没有关于丢失文件或目录的投诉。那么为什么我会从sed
收到错误?
为了节省一些挖掘答案和评论,结果证明这是sed
的BSD和GNU版本之间的差异。有关详情,请参阅this thread。
答案 0 :(得分:4)
如果您将附加信息传递给sed -i
,则需要将其与-i
相邻,如sed -i.bak myfile
中所示。它不能是一个单独的论点。 sed -i .bak myfile
会导致sed对名为.bak
和myfile
的文件进行编辑。
当您编写sed -i ''
sed尝试对名称为空字符串的文件进行现场编辑时。
如果您不想制作备份文件,请完全取消参数。否''
。
git grep --name-only "$grepexp" | xargs sed -r "$sedcmd" -i
答案 1 :(得分:2)
这不是一个真正的答案,这是一个调试步骤,但是发表评论的时间太长了。尝试创建名为print_args
的脚本:
#!/bin/bash
i=1
for arg
do
printf "Arg %d = '%s'\n" $i "$arg"
((i++))
done
然后尝试:
git grep --name-only "$grepexp" | xargs ./print_args sed -r "$sedcmd" -i ''
这应该显示传递给sed
的所有参数,你可能会看到一些解释为什么sed正在解析它的错误。
答案 2 :(得分:-2)
sed
可能会抱怨,因为您对可能包含分隔符的s/foo/bar/
和/或$foo
的值使用了$bar
命令 - /
。试试s%foo%bar/
或s@foo@bar
或其他您认为不会出现的分隔符。