Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 28 Jan 2005 08:40:57 +0200
From:      Giorgos Keramidas <keramida@ceid.upatras.gr>
To:        freebsd-questions@freebsd.org
Subject:   Re: One-line global string replace in all files with sed (or awk?)
Message-ID:  <20050128064057.GB1559@gothmog.gr>
In-Reply-To: <1098984237.20050128065616@wanadoo.fr>
References:  <1098984237.20050128065616@wanadoo.fr>

next in thread | previous in thread | raw e-mail | index | archive | help
On 2005-01-28 06:56, Anthony Atkielski <atkielski.anthony@wanadoo.fr> 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.

Indeed.

> 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 :-)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050128064057.GB1559>