0

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 file.ext.new.

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?

Keith Bentrup
  • 719
  • 3
  • 8
  • 19

6 Answers6

3

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/' {} +

Edit:

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.

Dan Carley
  • 25,617
  • 5
  • 53
  • 70
  • +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
1

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.

pyhimys
  • 1,287
  • 10
  • 10
0

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

mgorven
  • 30,615
  • 7
  • 79
  • 122
0

sed has a --in-place option.

retracile
  • 1,260
  • 7
  • 10
0

Perl rocks for this:

find . -type f -name '*.ext' | xargs perl -pi.bak -e 's/searchText/replaceText/g'
Justin Ellison
  • 718
  • 5
  • 9
0

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

Zombo
  • 1
  • 1
  • 16
  • 20