Command line: search and replace in all filenames matched by grep

Michael Kristofik picture Michael Kristofik · Jan 22, 2009 · Viewed 103.9k times · Source

I'm trying to search and replace a string in all files matched by grep:

grep -n 'foo' * will give me output in the form:

[filename]:[line number]:[text]

For each file returned by grep, I'd like to modify the file by replacing foo with bar.

Answer

MattJ picture MattJ · Jan 23, 2009

This appears to be what you want, based on the example you gave:

sed -i 's/foo/bar/g' *

It is not recursive (it will not descend into subdirectories). For a nice solution replacing in selected files throughout a tree I would use find:

find . -name '*.html' -print -exec sed -i.bak 's/foo/bar/g' {} \;

The *.html is the expression that files must match, the .bak after the -i makes a copy of the original file, with a .bak extension (it can be any extension you like) and the g at the end of the sed expression tells sed to replace multiple copies on one line (rather than only the first one). The -print to find is a convenience to show which files were being matched. All this depends on the exact versions of these tools on your system.