Test recursive sed search and replace before running

You could run sed without -i and step through output with less

grep -rl --null term1 . | xargs -0 sed -e 's/term1/term2/' | less

Then run sed with -i.bak to create backups which you can diff afterwards

grep -rl --null term1 . | xargs -0 sed -i.bak -e 's/term1/term2/'
diff somefile.bak somefile
# verify changes were correct

Edit: As suggested in comment, use grep --null | xargs -0. This causes filenames to be terminated by the null-byte, which makes it safe for filenames with unusual characters like newline. Yes, \n is a valid character in a unix filename. The only forbidden characters are slash / and the nul character \0


Use sed with find instead of grep

First of all, I would employ find rather than grep, and this for three good reasons:

  1. find allows for more precise file selection. For example, grep -r string *.txt will yield files only in the current directory; not those in subdirectories.
  2. find comes with the powerful -exec option which eliminates the need for the whole --null … |xargs 0 construct.
  3. The -readable and -writable options of find will prevent wasting time on files that cannot be accessed.

Capture test

That said, grep does lend itself for a first test to see what would be captured:

$ find . -exec grep term1 {} \;

or more specifically:

$ find . -type f -name '*.txt' -readable -writable -exec grep term1 {} \;

Dry run

Now, proceed with a sed dry run. The sed option -n is a synonym for --quiet and the p at the very end of the sed expression will print the current pattern space.

$ find . -exec sed -n 's/term1/term2/gp' {} \;

or more specifically:

$ find . -type f -name '*.txt' -readable -writable -exec sed -n 's/term1/term2/gp' {} \;

Execution

If everything looks fine, issue the definitive command by replacing sed option -n by -i for "in place" and by removing the p at the end.

$ find . -exec sed -i 's/term1/term2/g' {} \;

or more specifically:

$ find . -type f -name '*.txt' -readable -writable -exec sed -i 's/term1/term2/g' {} \;

More find examples

More find examples can be found here.

Tags:

Sed