Recursively find and replace with bash by leveraging the grep
and sed
command.
grep -rlG <regexp pattern> <path> | xargs sed -i '' 's/pattern/replacement/g'
grep
The G
flag for grep
enable regexp and l
makes it print path only then used as input by sed
.
sed
NOTE: On Mac OS we need to assign an empty argument for -i
flag,
or if you wanna backup then using an none empty argument, e.g. -i "backup"
sed
works as strem editor and s/pattern/replacement/g
means replace pattern
with repalcement
.
The pattern
can be plain text or regexp.
NOTE: if you wanna match words within the sed
pattern
part, instead of using \w+
,
which doesn't work with sed
, we need to use [a-z|A-Z]*.
$ grep -rlE "\/foo\/bar\/\w*?\/" . | xargs sed -i "" "s/\/foo\/bar\/[a-z|A-Z]*\//\.\//g"
the result would be:
- import sth from '/foo/bar/baz/quz'
+ import sth from './quz'
If the regexp are generated dynamically, that is to say, there's variable in the regexp pattern, note that we need to use double quotes.Single quotes prevent the shell variable from being interpolated by the shell.
e.g.:
arr=("foo" "bar")
for item in "${arr[@]}"
do
grep -rlE "\/src\/$item\/\w*?\/" . | xargs sed -i "" "s/\/src\/$item\/[a-z|A-Z]*\//\.\//g"
done