Bulk Search & Replace Commands for Files and Buffers in Emacs
29 Apr 2026 Charles Choi
Emacs offers a dizzying number of commands to perform bulk operations on multiple files or buffers. These commands are quite capable and can make trivial the execution of workflows that would be heroic in other editors. Unfortunately these commands are also difficult to discover as a number of them are not featured in easily accessible menus.
This post calls attention to bulk commands related to search and replace in Emacs and how their discoverability can be improved using the Casual and Anju UI packages.
Regular Expressions
Before moving forward, let’s talk about how Emacs handles regular expression syntax in search and/or replace commands. Whenever using an Emacs command involving a regular expression (regexp), you will need to understand what kind of regexp syntax is expected. There are largely two to know:
- Emacs
- grep (implementation dependent)
Commands using grep-style regexps do so because they invoke the local install of the grep utility. The grep regex syntax is implementation dependent. If you use GNU grep, you can read its syntax here, which share some character classes with Emacs.
The Casual RE-Builder package is a great way to work with Emacs regexps as it provides a command to escape the regexp properly for interactive input. re-builder alone only provides a regexp that can be used in Elisp code.
Bulk Search & Replace Commands
The table below shows the different search and/or replace workflows and their associated commands.
| Workflows | Command | Regexp Type | Notes |
|---|---|---|---|
| Search regexp in files in directory | rgrep | grep | AKA “Find in Files.” Results can be edited using writeable grep (wgrep). |
| Search regexp in files in project | project-find-regexp | grep | |
| Search regexp in files in directory and present in Dired | find-grep-dired | grep | |
| Search regexp in tagged files | tags-search | Emacs | |
| Search file names matching shell pattern in directory and present in Dired | find-name-dired | shell | |
| Search file names matching regexp in directory and present in Dired | find-lisp-find-dired | Emacs | Implementation uses Emacs regexp type. |
| Search file names matching regexp in current directory and present in Dired | casual-dired-find-dired-regexp | Emacs | Wrapper around find-lisp-find-dired using current directory. Available via Casual. |
| Query replace regexp in project files | project-query-replace-regexp | Emacs | |
| Incremental search marked files with plain text | dired-do-isearch | For use in Dired. | |
| Incremental search marked files with regexp | dired-do-isearch-regexp | Emacs | For use in Dired. |
| Query replace regexp in marked files | dired-do-query-replace-regexp | Emacs | For use in Dired. |
| Search regexp in marked files | dired-do-find-regexp | grep | For use in Dired. |
| Search regexp in marked files and display first match | dired-do-search | Emacs | For use in Dired. |
| Replace regexp in marked files | dired-do-find-regexp-and-replace | grep | For use in Dired. |
| Incremental search marked buffers with plain text | ibuffer-do-isearch | For use in IBuffer. | |
| Incremental search marked buffers with plain text with regexp | ibuffer-do-isearch-regexp | Emacs | For use in IBuffer. |
| View lines which match regexp in marked buffers | ibuffer-do-occur | Emacs | For use in IBuffer. |
| Query replace plain text in marked buffers | ibuffer-do-query-replace | For use in IBuffer. | |
| Query replace regexp in marked buffers | ibuffer-do-query-replace-regexp | Emacs | For use in IBuffer. |
Choice of command depends on the quantity and specificity of files or buffers to work on. Both Dired and IBuffer marking allow for specific selection of files or buffers respectively.
Many of the commands in the table above are discoverable via menu using the Casual and Anju packages. Hierarchical menu categorization aids in the discovery and recognition of these commands, making them more usable.
| Command | UI | Notes |
|---|---|---|
| rgrep | (C-o) casual-editkit-main-tmenu › (/) Search/Replace › (g) Find in Files… | Available via Casual EditKit. |
| rgrep | (Menu-bar) Edit › Search › Search in Files… | Available via Anju. |
| project-find-regexp | (Menu-bar) Edit › Search › Search in Project Files… | |
| tags-search | (Menu-bar) Edit › Search › Search Tagged Files… | |
| project-query-replace-regexp | (Menu-bar) Edit › Replace › Replace in Project Files… | |
| find-name-dired | (C-o) casual-editkit-main-tmenu › (/) Search/Replace › (d) Files… | Available via Casual EditKit. |
| find-grep-dired | (C-o) casual-editkit-main-tmenu › (/) Search/Replace › (G) Files containing text… | Available via Casual EditKit. |
| casual-dired-find-dired-regexp | (C-o) casual-dired-tmenu › (f) Filter by name… | Available via Casual Dired. |
| dired-do-isearch | (C-o) casual-dired-tmenu › (/) Search/Replace › (C-s) I-search… | Available via Casual Dired. |
| dired-do-isearch-regexp | (C-o) casual-dired-tmenu › (/) Search/Replace › (M-s) I-search regexp… | Available via Casual Dired. |
| dired-do-query-replace-regexp | (C-o) casual-dired-tmenu › (/) Search/Replace › (r) Query regexp and replace… | Available via Casual Dired. |
| dired-do-find-regexp | (C-o) casual-dired-tmenu › (/) Search/Replace › (g) Find regex… | Available via Casual Dired. |
| dired-do-search | (C-o) casual-dired-tmenu › (/) Search/Replace › (s) Search first regexp match… | Available via Casual Dired. |
| dired-do-find-regexp-and-replace | (C-o) casual-dired-tmenu › (/) Search/Replace › (G) Find regex and replace… | Available via Casual Dired. |
| ibuffer-do-isearch | (C-o) casual-ibuffer-tmenu › (C-s) I-Search… | Available via Casual IBuffer. |
| ibuffer-do-isearch-regexp | (C-o) casual-ibuffer-tmenu › (C-M-s) I-Search Regexp… | Available via Casual IBuffer. |
| ibuffer-do-occur | (C-o) casual-ibuffer-tmenu › (O) Occur… | Available via Casual IBuffer. |
| ibuffer-do-query-replace | (C-o) casual-ibuffer-tmenu › (M-r) Query Replace… | Available via Casual IBuffer. |
| ibuffer-do-query-replace-regexp | (C-o) casual-ibuffer-tmenu › (C-M-r) Query Replace Regexp… | Available via Casual IBuffer. |
Refactoring Guidance
The replace commands can do catastrophic damage if not used with caution. Treat them like power tools.
Some guidance before using replace commands:
-
Have a backup plan in case you need to recover anything.
-
Use
re-builderto help figure out the right regexp. -
Know the scope of what you want to change (directory, files, buffers).
-
Some commands will only modify the buffer of an affected file. Check if modified buffers are saved. You can use IBuffer to identify and save such buffers. It is left as an exercise to the reader to determine which commands exhibit this behavior.
Closing Thoughts
The inventory of commands above are from what I know of Emacs, which is guaranteed to not be comprehensive. If there are others missing from this list, please let me know at kickingvegas@gmail.com.
While many of these commands have been in Emacs for years (decades even), they were not usable to me until I built a UI for them. I think motivated readers using Casual and Anju for bulk search and/or replace tasks will find a similar sentiment.