-
-
Save jcamenisch/1671995 to your computer and use it in GitHub Desktop.
gg_replace() { | |
if [[ "$#" == "0" ]]; then | |
echo 'Usage:' | |
echo ' gg_replace term replacement file_mask' | |
echo | |
echo 'Example:' | |
echo ' gg_replace cappuchino cappuccino *.html' | |
echo | |
else | |
find=$1; shift | |
replace=$1; shift | |
ORIG_GLOBIGNORE=$GLOBIGNORE | |
GLOBIGNORE=*.* | |
if [[ "$#" = "0" ]]; then | |
set -- ' ' $@ | |
fi | |
while [[ "$#" -gt "0" ]]; do | |
for file in `git grep -l $find -- $1`; do | |
sed -e "s/$find/$replace/g" -i'' $file | |
done | |
shift | |
done | |
GLOBIGNORE=$ORIG_GLOBIGNORE | |
fi | |
} | |
gg_dasherize() { | |
gg_replace $1 `echo $1 | sed -e 's/_/-/g'` $2 | |
} |
True. But you can link to a fork if you have a recommended change. Copy/paste isn't too much work with this amount of code.
This is awesome. Thanks :)
Great to hear. Thanks!
Here's a case-insensitive version:
gg_ireplace() {
if [[ "$#" == "0" ]]; then
echo 'Usage:'
echo ' gg_ireplace term replacement file_mask'
echo
echo 'Example:'
echo ' gg_ireplace cappuccino Cappuccino *.html'
echo
else
find=$1; shift
replace=$1; shift
ORIG_GLOBIGNORE=$GLOBIGNORE
GLOBIGNORE=*.*
if [[ "$#" = "0" ]]; then
set -- ' ' $@
fi
while [[ "$#" -gt "0" ]]; do
for file in `git grep -Fil $find -- $1`; do
perl -pi -w -e "s/\Q$find\E/$replace/gi;" $file
done
shift
done
GLOBIGNORE=$ORIG_GLOBIGNORE
fi
}
Note the following, you may want to update your original script:
- Perl used for the regex, which allows for case-insensitive option
i
- Perl has
\Q...\E
, which allows us to make the$find
match literal - Usage of
git grep -F
for fixed-length string matching, makes initial search a bit faster
Also note that BSD sed command does not support the i
option... I don't know if there is any way to do this without Perl.
Odd, I get (on Mac) sed: -i may not be used with stdin
. Changing -i''
to -i ''
(with a space) fixes this, which makes sense: -i''
is exactly equivalent to -i
, I think, so it's treating $file
as the extension.
Here is my version that I use on Mac that handles filenames with 'Spaces'.
gg_replace() {
if [[ "$#" == "0" ]]; then
echo 'Usage:'
echo ' gg_replace term replacement file_mask'
echo
echo 'Example:'
echo ' gg_replace cappuchino cappuccino *.html'
echo
else
find=$1; shift
replace=$1; shift
ORIG_GLOBIGNORE=$GLOBIGNORE
GLOBIGNORE=*.*
if [[ "$#" = "0" ]]; then
set -- ' ' $@
fi
while [[ "$#" -gt "0" ]]; do
for file in `git grep -l $find -- $1 | sed -e "s/ /~~~~~/g"`; do
sed -i "" -e "s/$find/$replace/g" "${file/~~~~~/ }"
done
shift
done
GLOBIGNORE=$ORIG_GLOBIGNORE
fi
}
just a small tip for those trying to use this on OS X: install GNU sed (brew install gnu-sed
) and replace the sed
call with gsed
Here's my version: https://gist.github.com/glyph/9beafa8a7b26e5ca9f6666448fa5810d
gg_replace() {
if [[ "$#" -lt "2" ]]; then
echo "
Usage:
$0 term replacement file_mask
Example:
$0 cappuchino cappuccino '*.html'
";
else
local find="$1"; shift;
local replace="$1"; shift;
git grep -zlI "${find}" -- "$@" |
xargs -0 sed -e "s/${find}/${replace}/g" -i '' ;
fi;
}
A few notes:
- passes shellcheck
- doesn't depend on word splitting so doesn't need to monkey with
GLOBIGNORE
- supports spaces, newlines, and (apropos of dawalama's version ;-))
~~~~~
in path names - it still has the problem described in dwheeler's https://dwheeler.com/essays/filenames-in-shell.html section 3.3, since I couldn't figure out a quick way to make
git grep
prefix all its output with./
- it's a bit faster since it doesn't spawn new
sed
processes quite so many times
I guess the more direct way of doing that--with no external script file--would be with
or for one-line shorthand:
(Warning: my sh syntax is likely to be wrong when I write something and don't test it.)