Reputation: 69711
I have a little find-replace utility around git
. Let's ignore suggestions for a different approach ATM. I'm really trying to understand this error from sed
. Take a look at the command
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 ''
}
The command works, and I get the expected results, however, when I run this on one of my repositories, I get an error from sed
sed: can't read : No such file or directory
But the git
component returns a set of files that all exist (slightly mangled for sake of post)
git grep --name-only 0.46.1
release/a.html
release/resources/javascript/a.js
release/resources/version
release/index.html
release/installer.html
I've verified the existence of these files manually with ls
. For example, if I change the xargs
component to this
git grep --name-only 0.46.1 | xargs ls -l
There are no complaints from ls
about missing files or directories. So why do I get an error from sed
?
To save you some digging through the answers and comments, this turned out to be a difference between BSD and GNU versions of sed
. See this thread for more.
Upvotes: 2
Views: 2060
Reputation: 361977
If you pass an extension to sed -i
, it needs to be adjoined to the -i
, as in sed -i.bak myfile
. It can't be a separate argument. sed -i .bak myfile
would cause sed to do in place editing of files named .bak
and myfile
.
When you write sed -i ''
sed tries to do in place editing on a file whose name is the empty string.
If you don't want backup files made, just leave off the argument entirely. No ''
.
git grep --name-only "$grepexp" | xargs sed -r "$sedcmd" -i
Upvotes: 4
Reputation: 782130
This isn't really an answer, it's a debugging step, but it's too long to put in a comment. Try creating a script called print_args
:
#!/bin/bash
i=1
for arg
do
printf "Arg %d = '%s'\n" $i "$arg"
((i++))
done
Then try:
git grep --name-only "$grepexp" | xargs ./print_args sed -r "$sedcmd" -i ''
This should show all the arguments being passed to sed
, you may see something that explains why sed is parsing it incorrectly.
Upvotes: 2
Reputation: 767
sed
may be complaining because you are using the s/foo/bar/
command on values of $foo
and/or $bar
that may contain the delimiter -- /
. Try s%foo%bar/
or s@foo@bar
or some other delimiter you're confident will not appear.
Upvotes: -2