使用 Emacs 在尚未打开的文本文件中递归查找和替换

发布于 2024-07-08 04:34:35 字数 534 浏览 6 评论 0原文

作为此问题的后续问题,它试图找出如何做这样的事情,这应该很容易,这尤其阻止我更习惯使用 Emacs,而是启动我已经熟悉的编辑器。 我在编辑多个文件时经常使用这里的示例。

在 Ultraedit 中,我会先按 Alt+s,然后按 p 显示一个对话框,其中包含以下选项:查找(包括在多行中使用正则表达式)、替换为、在文件/类型中、目录、匹配大小写、仅匹配整个单词、列表更改的文件和搜索子目录。 通常我会首先使用鼠标单击并拖动选择要替换的文本。

仅使用 Emacs 本身(在 Windows XP 上),不调用任何外部实用程序,如何将 *.c*.h 文件中的所有 foo\nbar 替换为 bar\nbaz在某个文件夹及其下的所有文件夹中。 也许 Emacs 不是执行此操作的最佳工具,但是如何使用最少的命令轻松完成此操作呢?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

网白 2024-07-15 04:34:35
  1. Mx find-name-dired:系统将提示您输入根目录和文件名模式。
  2. t 为找到的所有文件“切换标记”。
  3. Q 表示“在文件中查询-替换...”:系统将提示您输入查询/替换正则表达式。
  4. 继续使用 query-replace-regexpSPACE 替换并移至下一个匹配项,n 跳过匹配项,等等。
  5. >Cx s 保存缓冲区。 (然后,您可以按 y 表示“是”,按 n 表示“否”,或按 ! 表示“是”)
  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)
撩动你心 2024-07-15 04:34:35
  • Mx find-name-dired RET
    • 可能需要一些时间所有文件才会出现在列表中,滚动到底部 (M->) 直到出现“find finish”以确保他们都已加载
  • t 为找到的所有文件“切换标记”
  • Q 为“文件中的查询-替换...”:系统将提示您查询/替换正则表达式。
  • 与 query-replace-regexp 一样继续:空格或 y 来替换并移动到下一个匹配项,n 来跳过匹配项等。
    • 输入! 在不询问的情况下替换当前文件中的所有匹配项,N 跳过当前文件其余部分的所有可能的替换。 (N 仅适用于 emacs 23+)
    • 要在不进一步询问的情况下对所有文件进行替换,请输入 Y
  • 调用“ibuffer”(Cx Cb,如果绑定到 ibuffer,或 Mx ibuffer RET)列出所有打开的文件。
  • 输入 * u 标记所有未保存的文件,输入 S 保存所有标记的文件
  • * * RET 取消标记所有标记,或输入 D 关闭所有标记的文件

此答案结合自 这个答案,来自这个网站,以及我自己的笔记。 使用 Emacs 23+。

  • M-x find-name-dired RET
    • it may take some time for all the files to appear in the list, scroll to bottom (M->) until "find finished" appears to make sure they all have loaded
  • Press t to "toggle mark" for all files found
  • Press Q for "Query-Replace in Files...": you will be prompted for query/substitution regexps.
  • Proceed as with query-replace-regexp: SPACE or y to replace and move to next match, n to skip a match, etc.
    • Type ! to replace all occurrences in current file without asking, N to skip all possible replacement for rest of the current file. (N is emacs 23+ only)
    • To do the replacement on all files without further asking, type Y.
  • Call “ibuffer” (C-x C-b if bound to ibuffer, or M-x ibuffer RET) to list all opened files.
  • Type * u to mark all unsaved files, type S to save all marked files
  • * * RET to unmark all marks, or type D to close all marked files

This answer is combined from this answer, from this site, and from my own notes. Using Emacs 23+.

与他有关 2024-07-15 04:34:35

弹丸真的很不错:
Cc pr 运行命令projectile-replace

Projectile is really nice:
C-c p r runs the command projectile-replace

少女情怀诗 2024-07-15 04:34:35

提供的答案很好,但是我想我应该添加一个稍微不同的方法。

这是一种更具交互性的方法,需要 wgreprgrepieditieditwgrep 都必须通过 MELPA 或 Marmalade 安装(使用 Mx package-list-packages

首先运行 Mx rgrep 找到您要查找的字符串。

您将能够指定文件类型/模式以及要递归的文件夹。

接下来,您需要运行 wgrep,并使用 Cs Cp 启动它。

Wgrep 将允许您编辑 rgrep 结果,因此在字符串上设置一个区域来匹配并使用 C-; 启动 iedit-mode (取决于在您的终端上,您可能需要重新绑定此)

所有出现的事件都可以立即编辑。 Cx Cs 提交 wgrep。 然后 Cx s ! 保存更改的文件。

此方法的主要好处是您可以使用 iedit-mode 关闭某些匹配 M-;。 您还可以使用 rgrep 中的结果跳转到文件,例如,如果您有意外的匹配项。

我发现它对于在项目中进行源代码编辑和重命名符号(变量、函数名称等)非常有用。

如果您还不知道/使用 iedit 模式,它是一个非常方便的工具,我强烈建议您看一下。

The answers provided are great, however I thought I'd add a slightly different approach.

It's a more interactive method, and requires wgrep, rgrep and iedit. Both iedit and wgrep must be installed via MELPA or Marmalade (using M-x package-list-packages)

First run M-x rgrep to find the string you're looking for.

You'll be able to specify file types/pattern and the folder to recurse.

Next you'll need to run wgrep start it with C-s C-p.

Wgrep will let you edit the rgrep results, so set a region on the string to match and start iedit-mode with C-; (depending on your terminal you may need to re-bind this)

All occurrences will be editable at once. C-x C-s to commit wgrep. Then C-x s ! to save the changed files.

The main benefit of this method is that you can use iedit-mode to toggle off certain matches M-;. You can also use the results in rgrep to jump into the files, for example if you have an unexpected match.

I find it very useful for doing source edits and renaming symbols (variables, function names etc.) across a project.

If you don't already know/use iedit mode it's a very handy tool, I strongly recommend you give it a look.

故人爱我别走 2024-07-15 04:34:35

我通常使用其他工具来执行此任务,似乎 EmacsWiki 的 Find and 中提到的许多方法Replace Across Files 条目 已经退出,但 Findr Package 看起来非常有前途。

窃取部分源文件

(defun findr-query-replace (from to name dir)
  "Do `query-replace-regexp' of FROM with TO, on each file found by findr.

I generally use other tools to perform this task, and it seems like many of the approaches mentioned at EmacsWiki's Find and Replace Across Files entry shell out, but the Findr Package looks very promising.

Stealing part of the source file:

(defun findr-query-replace (from to name dir)
  "Do `query-replace-regexp' of FROM with TO, on each file found by findr.
纸伞微斜 2024-07-15 04:34:35

信息来源:1

对于 emacs pro 用户:

  1. 拨打 dired 即可列出dir 中的文件,或者如果需要所有子目录,请调用 find-dired。
  2. 标记您想要的文件。 您可以通过输入【%m】来通过正则表达式进行标记。
  3. 输入 Q 调用 dired-do-query-replace-regexp。
  4. 输入您的查找正则表达式并替换字符串。 〔☛ 常见的 elisp 正则表达式模式〕
  5. 对于每个出现的情况,键入 y 进行替换,键入 n 进行跳过。 输入【Ctrl+g】即可中止整个操作。
  6. 类型 ! 在不询问的情况下替换当前文件中的所有匹配项,N 跳过当前文件其余部分的所有可能的替换。 (N 仅适用于 emacs 23)
  7. 要在不进一步询问的情况下对所有文件进行替换,请键入 Y。(仅适用于 Emacs 23)
  8. 调用 ibuffer 列出所有打开的文件。 输入【* u】标记所有未保存的文件,输入S保存所有标记的文件,输入D关闭它们。

Emacs 初学者分步指南

选择目标文件

在命令行界面提示符中键入“emacs”来启动 emacs。 (或者,如果您处于图形用户界面环境中,则双击 Emacs 图标)

选择目录中的文件

首先,您需要选择要进行替换的文件。 使用图形菜单〖文件 ▸ 打开目录〗。 Emacs 会要求您提供目录路径。 输入目录路径,然后按 Enter。

现在,您将看到文件列表,现在您需要标记您希望正则表达式查找/替换处理的文件。 您可以通过将光标移动到所需的文件来标记文件,然后按 m。 按 u 取消标记。 (要列出子目录,请将光标移至目录并按 i。子目录的内容将在底部列出。)要使用正则表达式标记所有文件,请键入【% m】,然后键入正则表达式模式。 例如,如果要标记所有 HTML 文件,则输入【% m】,然后输入 .html$。 (您可以在图形菜单“标记”中找到标记命令列表(当您处于直接模式时会出现此菜单)。)

选择目录及其所有子目录中的文件

如果您想要查找/替换对于目录(包括数百个子目录)内的文件,这里有一种选择所有这些文件的方法。

调用 find-dired。 (按【Alt+x】调用命令)然后,输入目录名, ⁖ /Users/mary/myfiles

注意:如果您在unix非图形文本终端上使用emacs,并且如果【Alt+x】不起作用,相当于按键是【Esc x】。

Emacs 会提示您“Run find (with args):”。 如果需要对所有 HTML 文件进行替换,请键入 -name "*html"。 如果您不关心什么类型的文件,而只关心该目录下的所有文件,则给出“-type f”。

现在,如上所述标记文件。

交互式查找/替换

现在,您已准备好进行交互式查找替换。 为简单起见,假设您只想将“快速”一词替换为“超级”。 现在,调用 dired-do-query-replace-regexp。 它将提示您输入正则表达式字符串和替换字符串。 输入“quick”,然后输入“super”。

现在,emacs 将使用您的模式并检查文件,并在发生匹配时停止并向您显示。 发生这种情况时,emacs 会提示您,您可以选择进行更改或跳过更改。 要进行更改,请键入 y。 要跳过,请输入 n。 如果您只是想让 emacs 继续对当前文件进行所有此类更改,请输入 !。

如果您想取消整个操作而不保存所做的任何更改,请输入【Ctrl+g】,然后使用菜单〖文件▸退出Emacs〗退出emacs。

保存更改的文件

现在,在经历了上述磨难之后,您还需要做一步,那就是保存更改的文件。

如果您使用的是 emacs 22 或更高版本,则调用 ibuffer 进入缓冲区列表模式,然后输入【* u】标记所有未保存的文件,然后输入 S 保存所有文件。 (即shift-s)

如果您使用的是emacs版本21,那么您可以执行以下操作:调用list-buffers,然后将光标移动到要保存的文件并输入s。 它将标记文件以供以后保存操作。 输入 u 取消标记。 完成后,输入 x 来执行所有标记为保存的文件的保存。 (在emacs中,打开的文件被称为“buffer”。忽略那里的其他东西。)

除了上述选项之外,您还可以调用save-some-buffers【Ctrl+xs】。 然后 emacs 将显示每个未保存的文件并询问您是否要保存它。

注意:emacs 的正则表达式与 Perl 或 Python 的不同,但类似。 有关摘要和常见模式,请参阅:Emacs Regex。

Source of information: 1

For emacs pro users:

  1. Call dired to list files in dir, or call find-dired if you need all subdirectories.
  2. Mark the files you want. You can mark by regex by typing 【% m】.
  3. Type Q to call dired-do-query-replace-regexp.
  4. Type your find regex and replace string. 〔☛ common elisp regex pattern〕
  5. For each occurrence, type y to replace, n to skip. Type 【Ctrl+g】 to abort the whole operation.
  6. Type ! to replace all occurrences in current file without asking, N to skip all possible replacement for rest of the current file. (N is emacs 23 only)
  7. To do the replacement on all files without further asking, type Y. (Emacs 23 only)
  8. Call ibuffer to list all opened files. Type 【* u】 to mark all unsaved files, type S to save all marked files, type D to close them all.

Step-by-Step Guide for Emacs Beginners

Select Target Files

Start emacs by typing “emacs” in the command line interface prompt. (Or, double click the Emacs icon if you are in a Graphics User Interface environment)

Selecting Files in a Directory

First you need to select the files you want to do the replace. Use the graphical menu 〖File ▸ Open Directory〗. Emacs will ask you for a directory path. Type the directory path, then press Enter.

Now, you will be shown the list of files, and now you need to mark the files you want the regex find/replace to work on. You mark a file by moving the cursor to the file you want, then press m. Unmark it by pressing u. (To list subdirectories, move your cursor to the directory and press i. The sub-directory's content will be listed at the bottom.) To mark all files by a regex, type 【% m】, then type your regex pattern. For example, if you want to mark all HTML files, then type 【% m】 then .html$. (You can find a list of the mark commands in the graphical menu “Mark” (this menu appears when you are in the dired mode).)

Selecting Files in a Directory and All Its Sub-Directories

If you want to do find/replace on files inside a directory, including hundreds of subdirectories, here's a method to select all these files.

Call find-dired. (you call a command by pressing 【Alt+x】) Then, type a directory name, ⁖ /Users/mary/myfiles

Note: if you are using emacs on a unix non-graphical text terminal, and if 【Alt+x】 does not work, the equivalent key stroke is 【Esc x】.

Emacs will ask you with the prompt “Run find (with args): ”. If you need to do the replacement on all HTML files, then type -name "*html". If you don't care about what kind of file but simply all files under that dir, then give “-type f”.

Now, mark the files as described above.

Interactive Find/Replace

Now, you are ready to do the interactive find replace. For simplicity, let's say you just want to replace the word “quick” by “super”. Now, call dired-do-query-replace-regexp. It will prompt you for the regex string and the replacement string. Type “quick”, enter, then “super”.

Now, emacs will use your pattern and check the files, and stop and show you whenever a match occurred. When this happens, emacs will prompt you, and you have a choice of making the change or skip the change. To make the change, type y. To skip, type n. If you simply want emacs to go ahead and make all such changes to the current file, type !.

If you want to cancel the whole operation without saving any changes you've made, type 【Ctrl+g】, then exit emacs using the menu 〖File ▸ Exit Emacs〗.

Saving the Changed Files

Now, after you went through the above ordeal, there is one more step you need to do, and that is saving the changed files.

If you are using emacs version 22 or later, then call ibuffer to go into a buffer listing mode, then type 【* u】 to mark all unsaved files, then type S to save them all. (that's shift-s)

If you are using a emacs version 21, then you can do this: call list-buffers, then move the cursor to the file you want to save and type s. It will mark the file for later save action. Type u to unmark. Once you are done, type x to execute the saving of all files marked for save. (in emacs, opened file is called “buffer”. Disregard other things there.)

Alternative to the above options, you can also call save-some-buffers 【Ctrl+x s】. Then emacs will display each unsaved file and ask if you want it saved.

Note: emacs's regex is not the same as Perl or Python's, but similar. For a summary and common patterns, see: Emacs Regex.

冷了相思 2024-07-15 04:34:35

使用 dired 递归深层目录树对于此任务来说会有点慢。 您可以考虑使用 tags-query-replace 。 这确实意味着要花很多钱来创建标签表,但这通常很有用,而且速度很快。

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.

白龙吟 2024-07-15 04:34:35

对于开放缓冲区,这就是我所做的:

(defun px-query-replace-in-open-buffers (arg1 arg2)
  "query-replace in all open files"
  (interactive "sRegexp:\nsReplace with:")
  (mapcar
   (lambda (x)
     (find-file x)
     (save-excursion
       (goto-char (point-min))
       (query-replace-regexp arg1 arg2)))
   (delq
    nil
    (mapcar
     (lambda (x)
       (buffer-file-name x))
     (buffer-list)))))

For open buffers, this is what I do :

(defun px-query-replace-in-open-buffers (arg1 arg2)
  "query-replace in all open files"
  (interactive "sRegexp:\nsReplace with:")
  (mapcar
   (lambda (x)
     (find-file x)
     (save-excursion
       (goto-char (point-min))
       (query-replace-regexp arg1 arg2)))
   (delq
    nil
    (mapcar
     (lambda (x)
       (buffer-file-name x))
     (buffer-list)))))
饮惑 2024-07-15 04:34:35

MX Dired,t 标记所有文件,Q 查询所有文件中的替换文本。
您可以在查询替换之前使用 i 命令来展开子目录。
我添加的关键信息是,如果您为 i 命令提供前缀(control-u),
它会提示您输入 arg,并且 -R 参数将递归展开所有子目录
进入dired缓冲区。 所以现在您可以查询搜索整个目录中的每个文件。

M-X Dired, and t to mark all files, and Q to query replace text in all of them.
You can expand a sub directory by using the i command before the query-replace.
They key info I'm adding is that if you give a prefix (control-u) to the i command,
it will prompt you for arg, and -R argument will recursively expand all subdirs
into the dired buffer. So now you can query-search every file in an entire directory.

葬﹪忆之殇 2024-07-15 04:34:35

另一种选择是使用 Icicles 搜索。 这是一种不同类型的增量搜索,它使用迷你缓冲区输入的完成来对抗搜索命中。 当您修改当前输入时,缓冲区 *Completions* 中的匹配匹配集会更新。

您可以搜索任意数量的文件、缓冲区或加书签的位置,您可以使用迷你缓冲区模式(例如正则表达式)匹配来选择它们。

当您访问搜索命中时,您可以根据需要替换整个命中或者只是与您当前的迷你缓冲区输入相匹配的部分。 按需替换意味着您不会依次查询每个搜索命中; 您可以按任何顺序直接访问您想要的点击。 如果您要进行的替换数量有限,则此方法可能比查询替换更有效:您可以跳过详尽的 y/n 提示。

搜索是在您定义的上下文上进行搜索——您不限于搜索目标文件中的所有文本(例如,您可以跳过注释或特定类型的程序部分)。 搜索上下文的一个简单示例是一行,如 grep 中所示,但上下文可以是您喜欢的任何模式匹配的文本块。 通常,您使用正则表达式定义搜索上下文,但您也可以使用函数。 除了定义您自己的之外,还有针对不同类型上下文的预定义 Icicles 搜索命令:文本属性块或覆盖属性、点对点事物等。

您还可以对搜索结果进行排序采用各种排序顺序,以便于访问/导航。

Another option is to use Icicles search. This is a different kind of incremental search that uses completion of your minibuffer input against search hits. As you modify your current input the set of matching hits is updated in buffer *Completions*.

You can search any number of files, buffers, or bookmarked locations, which you can choose using minibuffer pattern (e.g. regexp) matching.

When you visit a search hit you can replace on demand either the entire hit or just the part of it that matches your current minibuffer input. Replacement on demand means you are not queried about each search hit in turn; you access the hits you want directly, in any order. This approach can be more effective than query-replace if you have a limited number of replacements to make: you skip the exhaustive y/n prompting.

Search is over search contexts that you define -- you are not limited to searching all of the text in the target files (e.g., you can skip comments or particular kinds of program sections). A simple example of a search context is a line, as in grep, but a context can be any pattern-matched block of text you like. Typically you define the search contexts using a regexp, but you can instead use a function. In addition to defining your own, there are predefined Icicles search commands for different kinds of contexts: blocks of text properties or overlay properties, thing-at-point things, etc.

You can also sort the search hits in various sort orders for easier access/navigation.

那一片橙海, 2024-07-15 04:34:35

find-name-dired 没问题,但是:

  • 您获得的所有文件都匹配相同的单个正则表达式。
  • find-dired 在这方面更加灵活,但它也是为使用通用规则而设计的(即使它们可以任意复杂)。 当然,find 有其自己的复杂语言。
  • 如果您只想对 find(-name)-dired 缓冲区中收集的名称的某些文件执行操作,则需要标记它们或删除/省略您执行的操作的行不想采取行动。

另一种方法是使用 Dired+< /a> 命令作用于 (a) 标记的文件和 (b) 标记子目录中的所有标记文件(或所有文件,如果没有标记)...递归地发现< /em>. 这为您提供了通用性和对文件选择的轻松控制。 这些“此处和下方”命令均位于 Dired 模式下的前缀键 M-+ 上。

例如,M-+ QQ --- 查询-替换相同,但目标文件是所有标记的文件当前目录和任何标记的子目录中,向下,向下,向下...

是的,使用此类此处和下面命令的替代方法是递归地插入所有子目录及其子目录,然后使用顶级命令,例如Q。 但通常不用担心插入的子目录会很方便。

为此,您无论如何都需要一种快速方法来递归地插入所有此类子目录。 在这方面,Dired+ 也能提供帮助。 M-+ Mi 递归地插入所有标记的子目录及其自己的标记子目录。 也就是说,它类似于 Mi (将标记的子目录插入到 Dired+ 中),但它对子目录进行递归操作。

(所有此类“此处和下方”Dired+ 命令均位于菜单多个 > 在此处和下方标记。)

您还可以执行 Dired对 Emacs 文件集的操作,文件集是位于任意位置的一组保存的文件名。 如果您使用 Icicles那么您可以仅为文件集中的文件或其他类型的已保存文件列表打开 Dired 缓冲区。

您还可以为任何 Dired 缓冲区添加书签,包括使用 find(-name)-dired 创建的缓冲区。 这为您提供了稍后返回到此类集合(例如项目集)的快速方法。 如果您使用Bookmark+ 然后为 Dired 缓冲区添加书签,记录 (a) 其 ls 开关、(b) 标记了哪些文件、(c) 插入了哪些子目录以及 (d) 隐藏了哪些(子)目录。 当您“跳转”到书签时,所有这些都会恢复。 Bookmark+ 还允许您为 Dired 缓冲区的整个树添加书签 --- 跳转到书签会恢复树中的所有缓冲区。

find-name-dired is OK, but:

  • All of the files you get match the same, single regexp.
  • find-dired is more flexible in that regard, but it too is made for using general rules (even if they can be arbitrarily complex). And of course find has its own, complex language.
  • if you then want to act on only some of the files whose names were collected in the find(-name)-dired buffer, you need to either mark them or delete/omit the lines of those you do not want to act on.

An alternative is to use Dired+ commands that act on (a) the marked files and (b) all marked files (or all files, if none are marked) in the marked subdirectories ... found recursively. This gives you both generality and easy control over file choice. These "here-and-below" commands are all on prefix key M-+ in Dired mode.

For example, M-+ Q is the same as Q --- query-replace, but the target files are all of those marked in the current dir and in any marked subdirs, down, down, down...

Yes, an alternative to using such here-and-below commands is to insert all subdirs and their subdirs, recursively, and then use a top-level command such as Q. But it can often be convenient not to bother with inserted subdirs.

And to do that you anyway need a quick way to insert all such subdirs recursively. Here too, Dired+ can help. M-+ M-i inserts all marked subdirs and their own marked subdirs, recursively. That is, it is like M-i (which inserts the marked subdirs in Dired+), but it acts recursively on subdirs.

(All such "here-and-below" Dired+ commands are on menu Multiple > Marked Here and Below.)

You can also perform Dired operations on an Emacs fileset, which is a saved set of names of files located anywhere. And if you use Icicles then you can open a Dired buffer for just the files in a fileset or other types of saved file lists.

You can also bookmark any Dired buffer, including one that you create using find(-name)-dired. This gives you a quick way to return to such a set (e.g. a project set) later. And if you use Bookmark+ then bookmarking a Dired buffer records (a) its ls switches, (b) which files are marked, (c) which subdirectories are inserted, and (d) which (sub)directories are hidden. All of that is restored when you "jump" to the bookmark. Bookmark+ also lets you bookmark an entire tree of Dired buffers --- jumping to the bookmark restores all of the buffers in the tree.

满意归宿 2024-07-15 04:34:35
  1. Mx project-query-replace-regexp RET(确保您的文件已保存!)。

  2. Mx rgrep RET 然后在每个缓冲区内query-replace。 很好,因为您可以跟踪所有出现的情况,并且可以让您将搜索限制为某些扩展名。

  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.

冬天旳寂寞 2024-07-15 04:34:35

我想推荐一个尚未提及的好工具,即 Helm

它是许多涉及补全、搜索等标准 Emacs 操作的绝佳替代品。特别是,helm-find-files 允许在多个选定文件中执行查询替换(包括正则表达式)。

只需打开 helm-find-files,用 M-SPC 标记相关文件,然后使用 F6F7在选定的文件中运行查询替换或查询替换正则表达式。

I would like to suggest one more great tool which has not been mentioned yet, namely Helm.

It is a great replacement for many standard Emacs operations involving completion, searching etc. In particular, helm-find-files allows for performing query replace (including regexp) within multiple selected files.

Just open helm-find-files, mark the relevant files with M-SPC and then use F6 or F7 to run query replace or query replace regexp in the selected files.

開玄 2024-07-15 04:34:35

令人惊讶的是,对于使用针对此类情况创建的 -batch Emacs 模式,尚未给出任何答案。 这是一个简单的例子:

$ echo foo > 1 && echo foo > 2 && echo foo > 3
$ emacs -batch --eval '(progn (dolist (file command-line-args-left) (find-file file) (replace-regexp "foo" "bar") (save-buffer) (kill-buffer)))' ./1 ./2 ./3
Mark set
Replaced 1 occurrence
Mark set
Replaced 1 occurrence
Mark set
Replaced 1 occurrence
$ grep "" ./1 ./2 ./3
./1:bar
./2:bar
./3:bar

值得注意的是,如果您的替换内容不适合小单行,您也可以将其保存到如下文件中:

$ cat my_replace.el
(dolist (file command-line-args-left)
  (find-file file)
  (replace-regexp "foo" "bar")
  (save-buffer)
  (kill-buffer))
$ emacs -batch -l my_replace.el ./1 ./2 ./3
Mark set
Replaced 1 occurrence
Mark set
Replaced 1 occurrence
Mark set
Replaced 1 occurrence

Surprisingly, no answer was given yet to make use of -batch Emacs mode that has been created for situations like this. So here's a simple example:

$ echo foo > 1 && echo foo > 2 && echo foo > 3
$ emacs -batch --eval '(progn (dolist (file command-line-args-left) (find-file file) (replace-regexp "foo" "bar") (save-buffer) (kill-buffer)))' ./1 ./2 ./3
Mark set
Replaced 1 occurrence
Mark set
Replaced 1 occurrence
Mark set
Replaced 1 occurrence
$ grep "" ./1 ./2 ./3
./1:bar
./2:bar
./3:bar

Worth noting separately that if your replacement does not fit into a small one-liner you can also save it to a file like this:

$ cat my_replace.el
(dolist (file command-line-args-left)
  (find-file file)
  (replace-regexp "foo" "bar")
  (save-buffer)
  (kill-buffer))
$ emacs -batch -l my_replace.el ./1 ./2 ./3
Mark set
Replaced 1 occurrence
Mark set
Replaced 1 occurrence
Mark set
Replaced 1 occurrence
踏月而来 2024-07-15 04:34:35

它不是 Emacs,但 xxdiff 附带了一个名为 xx-rename 的工具,该工具可以一次对多个字符串执行此操作(例如 From To from to FROM TO),并带有交互式提示,保存所有修改文件的备份,并生成一个简短的文件根据上下文进行的更改日志。 这就是我在进行大型/全局重命名时倾向于使用的方法。

It's not Emacs, but xxdiff comes with a tool called xx-rename which will do that for multiple strings at a time (e.g. From To from to FROM TO), with interactive prompting, save backups of all the modified files, and produce a short log of changes made with context. That's what I tend to use when I do large/global renamings.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文