tags:

views:

2329

answers:

4

I'm trying to search and replace a string in all files matched by grep on a linux machine. I've got some pieces of what I want to do, but I'm unsure how best to string them all together.

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

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

For each file returned by grep, I'd like replace "foo" with "bar" and write the result back to the file. Is there a good way to do that? Maybe a fancy pipeline?

UPDATE:

I've modified my question to hopefully make it clearer.

+11  A: 

Do you mean search and replace a string in all files matched by grep?

perl -p -i -e 's/oldstring/newstring/g' `grep -ril searchpattern *`
armandino
+5  A: 

If your sed(1) has a -i option, then use it like this:

for i in *; do
  sed -i 's/foo/bar/' $i
done

If not, there are several ways variations on the following depending on which language you want to play with:

ruby -i.bak -pe 'sub(%r{foo}, 'bar')' *
perl -pi.bak -e 's/foo/bar/' *
Keltia
+5  A: 

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.

MattJ
A: 

I like and used the above solution or a system wide search and replace among thousands of files:

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

I assume with the '*.htm?' instead of .html it searches and finds .htm and .html files alike.

I replace the .bak with the more system wide used tilde (~) to make clean up of backup files easier.

hans