On macOS, none of the answers worked for me. I discovered that was due to differences in how sed
works on macOS and other BSD systems compared to GNU.
In particular BSD sed
takes the -i
option but requires a suffix for the backup (but an empty suffix is permitted)
grep
version from this answer.
grep -rl 'foo' ./ | LC_ALL=C xargs sed -i '' 's/foo/bar/g'
find
version from this answer.
find . \( ! -regex '.*/\..*' \) -type f | LC_ALL=C xargs sed -i '' 's/foo/bar/g'
Don't omit the Regex to ignore .
folders if you're in a Git repo. I realized that the hard way!
That LC_ALL=C
option is to avoid getting sed: RE error: illegal byte sequence
if sed
finds a byte sequence that is not a valid UTF-8 character. That's another difference between BSD and GNU. Depending on the kind of files you are dealing with, you may not need it.
For some reason that is not clear to me, the grep
version found more occurrences than the find
one, which is why I recommend to use grep
.