Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

So I want to change several files at one with one command. This is what I have so far:

find -regex ".*\.ext$" | xargs grep -l searchText 2> /dev/null | xargs -i sed 's/searchText/replaceText/' > {}.new

What it does:

I find files with extension ext, send it to grep ignoring errors, and then send it to sed for replacement with new filename

The problem seems to be that the redirect > in the sed prevents the {} from being replaced with the filename.

Any ideas? or a better solution?

share|improve this question
up vote 3 down vote accepted

If you can live with the file being updated in place and a backup created.

find -name '*.ext' -exec sed -i'.backup' 's/searchText/replaceText/' {} +


If you absolutely can't have the files that way round - modified file in place and original with an extension - then you could bolt an extra command on the end of the exec to move them around.

share|improve this answer
+1 Good stuff. Still want to send through grep to make sure I don't end up modding unnecessary files. Otherwise, it will change the timestamp and leave lots of backups of unmodified files. – Keith Bentrup Aug 13 '09 at 17:07

Backticks aka. "External commands" to the rescue.

sed -i '.bak' 's/searchText/replaceText/g' `grep -l searchText \`find . -name '*.ext'\``

Here we have find searching for '*.ext' which is then given as files to search for grep which are the given to sed which does the actual replacing. It has the advantage that it doesn't spawn new grep process for every file that is found. Ditto for sed.

share|improve this answer

sed has a --in-place option.

share|improve this answer

Perl rocks for this:

find . -type f -name '*.ext' | xargs perl -pi.bak -e 's/searchText/replaceText/g'
share|improve this answer

Yeah, Perl rocks for this and here is a whole script for this purpose.

share|improve this answer

You can use Vim in Ex mode:

find -name '*.ext' -exec ex -sc '%s/OLD/NEW/g|x' {} ';'
  1. % select all lines

  2. s substitute

  3. g replace all instances in each line

  4. x save and close

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.