Using Emacs to recursively find and replace in text files not already open

Viewed 61800

As a follow-up to this question, it's trying to find out how to do something like this which should be easy, that especially stops me from getting more used to using Emacs and instead starting up the editor I'm already familiar with. I use the example here fairly often in editing multiple files.

In Ultraedit I'd do Alt+s then p to display a dialog box with the options: Find (includes using regular expressions across multiple lines), Replace with, In Files/Types, Directory, Match Case, Match Whole Word Only, List Changed Files and Search Sub Directories. Usually I'll first use the mouse to click-drag select the text that I want to replace.

Using only Emacs itself (on Windows XP), without calling any external utility, how to replace all foo\nbar with bar\nbaz in *.c and *.h files in some folder and all folders beneath it. Maybe Emacs is not the best tool to do this with, but how can it be done easily with a minimal command?

14 Answers
  1. M-x find-name-dired: you will be prompted for a root directory and a filename pattern.
  2. Press t to "toggle mark" for all files found.
  3. Press Q for "Query-Replace in Files...": you will be prompted for query/substitution regexps.
  4. Proceed as with query-replace-regexp: SPACE to replace and move to next match, n to skip a match, etc.
  5. Press C-x s to save buffers. (You can then press y for yes, n for no, or ! for yes for all)

Using dired to recurse down a deep directory tree is going to be a bit slow for this task. You might consider using tags-query-replace. This does mean shelling out to create a tags table, but that is often useful anyway, and it's quick.

  1. M-x project-query-replace-regexp RET (make sure your files are saved!).

  2. M-x rgrep RET then query-replace within each buffer. Nice because you can keep track of all occurrences, and because it let's you limit search to certain extensions.

Related