使用Vim在所有文件中进行交互式查找和替换,包括子目录中的文件

时间:2019-04-20 13:57:52

标签: regex bash vim

我想用Vim查找某些字符串并将其替换为另一个。对于每次替换,它都应要求确认,类似于%s/foo/replace/gc对Vim中的单个文件所做的确认。

我尝试了什么?

  1. sed:它不进行交互式替换。
  2. 以下this link中的注释之一建议vim -esnc '%s/foo/bar/g|:wq' file.txt。我尝试了vim -esnc '%s/foo/bar/gc|:wq' file.txt(使用 gc 而不是 g )。现在终端卡住了。
  3. Emacs xah-find-replace package。不幸的是,它没有按照链接中的承诺进行交互式替换。

3 个答案:

答案 0 :(得分:2)

如果您正在寻找一种交互式的替换方式,那么使用vim会更容易。

vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' FILENAME

您遇到的终端卡死是由于将save命令传递到替换字符串,因为它不允许交互模式生效。而且它不是卡住的终端,如果您键入“是”并按Enter,它仍将显示预期的结果。

如果涉及多个文件,这些文件分布在多个子目录中,则使用带for循环的find命令将有帮助,如下所述:

for FILENAME in `find DIRECTORYPATH -type f -name *.txt` 
do 
    vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' $FILENAME
done

答案 1 :(得分:2)

建议将:argdo与替代命令结合使用。

您可以通过打开所有文件vim *.txt来填充args,也可以在打开vim之后使用以下命令手动填充args:

:args `find . -type f -name '*.txt'`

现在使用以下命令隐藏:

:set hidden

这是必需的,这样当从一个缓冲区切换到另一个缓冲区时,不会提示您保存文件。有关更多信息,请参见:h hidden

现在像以前一样使用替代命令,为argdo加上前缀以对argslist中的每个文件执行此操作

:silent argdo %s/pattern/replace/gec

silent是可选的,只是使报告静音。 e标志用于停止报告某些缓冲区中找不到匹配项的错误消息

现在替换后,您可以使用以下命令写入更改

:argdo update

这将写入仅被修改的缓冲区。

答案 2 :(得分:1)

在bash中打开双星以列出所有子目录中的所有文件:

shopt -s globstar

现在对所有文件启动一次vim,然后对所有文件运行替代命令,然后保存并退出:

vim -c 'set nomore' -c 'argdo %s/foo/bar/gc' -c xa **/*.txt