令人困惑的错误来自| xargs sed

时间:2014-01-29 19:56:51

标签: git bash replace sed xargs

我在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

3 个答案:

答案 0 :(得分:4)

如果您将附加信息传递给sed -i,则需要将其与-i相邻,如sed -i.bak myfile中所示。它不能是一个单独的论点。 sed -i .bak myfile会导致sed对名为.bakmyfile的文件进行编辑。

当您编写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或其他您认为不会出现的分隔符。