Reputation: 1097
How to pass argument to sed without input files. The sed is in single quote and has pipe in it already.
git filter-branch -f --index-filter \
'git ls-files -s | sed -i "s-\t\"*-&dirname/-" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
git update-index --index-info &&
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
The above code works fine if dirname is hard-coded. But i need to pass the dirname from command line arguments to script. I am trying like below but no luck.
'set subdir=$folder;git ls-files -s | sed -i "s-\t\"*-&$subdir/-" |
The sed says input file is missing. I can not directly pass the input file to sed. I am seeing error like below.
Rewrite 9c86de42b7f3228e3d45a278c8caf7e24c8e55cf (1/2) (0 seconds passed, remaining 0 predicted)
sed: no input files
Upvotes: 0
Views: 371
Reputation: 488233
You have two choices here. You can either evaluate $subdir
to build up a fixed sed
command that you then set as your filter; or you can evaluate a variable in the shell fragment that git filter-branch
will invoke.
To understand the latter, realize that your --index-filter
string becomes an ordinary shell variable:
--index-filter)
filter_index="$OPTARG"
;;
which is then passed to eval
:
eval "$filter_index" < /dev/null ||
die "index filter failed: $filter_index"
The eval
means that the expression in $filter_index
, set from your --index-filter
argument, has access to all the shell variables and functions in the filter-branch script. Unfortunately, none of its private variables holds the expression you'd like—but you can access its environment variables, which means you can put the value into an environment variable. In other words, you could supply subdir=<whatever>
as an environment to your original expression.
In any case, as bk2204 answered, you need to remove the -i
option. Besides that, some versions of sed
don't accept \t
as a tab character (presumably yours does, just be aware of this).
To expand the variable earlier, just do that. For instance:
... --index-filter \
'git ls-files -s | sed "s-\t\"*-&'$folder'/-" | ...
(I've removed the -i
here myself). Note how this exits single quotes, expands $folder
, then re-enters single quotes. If $folder
might contain whitespace, be sure to use double quotes while expanding it here:
... --index-filter \
'git ls-files -s | sed "s-\t\"*-&'"$folder"'/-" | ...
The nesting of quotes here is pretty tricky: the stuff inside the single quotes is all one big string, provided as the argument that sets the variable $filter_index
inside the filter-branch
script. The eval
runs it through a second pass of evaluation, breaking up into the pipeline (git ls-files
, piped to sed
, piped to git update-index
) and running the various multiple commands, all of which have their stdin redirected to /dev/null
.
Upvotes: 2
Reputation: 76519
You're using sed -i
, which edits its command-line arguments (which are names of files) in place. However, you're reading from standard input and haven't provided any command-line arguments. If you want to just filter the standard input like this, omit the -i
from your sed
command.
Upvotes: 2