One-line global string replace in all files with sed (or awk?)

Giorgos Keramidas keramida at
Thu Jan 27 22:41:04 PST 2005

On 2005-01-28 06:56, Anthony Atkielski <atkielski.anthony at> wrote:
> My thanks to all who replied.  I ended up using this form (I don't
> recall who suggested it):
> find . -type f | xargs sed -i '' -e 's/foo/bar/g'
> One problem, though:  It appears that sed touches every file, resetting
> the last modification time, even if it didn't actually change anything.


> This reset the last modification dates for every file on my site, which
> wasn't much fun.

Oops.  Sorry about that :-/

> Is there another command I could put between find and xargs that would
> filter only the names of files containing the string?  (grep would do
> it, but grep outputs the lines found to stdout, so that won't do.)

grep will do.  You just have to pass it the right option:

	find . -type f | xargs grep -l 'foo' | \
	    xargs sed -i '' -e 's/foo/bar/g'

When passed the -l option (this is a lowercase 'EL'), it will not print
the matched lines.  Only the name of the files that *do* match.  Then,
once you have a list of files that really do match with 'foo' as a
pattern, you can xargs sed on the list to substitute whatever you want :-)

More information about the freebsd-questions mailing list