使用脚本将正则表达式替换全局应用于许多文件 [英] Apply regular expression substitution globally to many files with a script
问题描述
我想对一个目录中和目录下的大约 40 个 Javascript 文件全局应用某个正则表达式替换.我是 vim 用户,但手动执行此操作可能很乏味且容易出错,因此我想使用脚本使其自动化.
I want to apply a certain regular expression substitution globally to about 40 Javascript files in and under a directory. I'm a vim user, but doing this by hand can be tedious and error-prone, so I'd like to automate it with a script.
我尝试过 sed,但一次处理多于一行是很尴尬的,尤其是在模式可能匹配的行数没有限制的情况下.
I tried sed, but handling more than one line at a time is awkward, especially if there is no limit to how many lines the pattern might match.
我也试过这个脚本(在单个文件上,用于测试):
I also tried this script (on a single file, for testing):
ex $1 <<EOF
gs/,\(\_\s*[\]})]\)/\1/
EOF
该模式将消除任何 Perl/Ruby 样式列表中的尾随逗号,因此[a, b, c,]"将显示为[a, b, c]"以满足 Internet Explorer,在浏览器中仅此一项,就在此类列表中窒息.
The pattern will eliminate a trailing comma in any Perl/Ruby-style list, so that "[a, b, c,]" will come out as "[a, b, c]" in order to satisfy Internet Explorer, which alone among browsers, chokes on such lists.
该模式在 vim 中运行良好,但如果我按照上述脚本在 ex 中运行它,则什么也不做.
The pattern works beautifully in vim but does nothing if I run it in ex, as per the above script.
谁能看到我可能遗漏了什么?
Can anyone see what I might be missing?
推荐答案
您要求提供脚本,但您提到您是 vim 用户.我倾向于在 vim 内部进行项目范围的查找和替换,如下所示:
You asked for a script, but you mentioned that you are vim user. I tend to do project-wide find and replace inside of vim, like so:
:args **/*.js | argdo %s/,\(\_\s*[\]})]\)/\1/ge | update
这与另一位评论者提到的 :bufdo
解决方案非常相似,但它将使用您的 args 列表而不是您的 buflist(因此不需要全新的 vim 会话,也不需要您小心关闭您不想触及的缓冲区).
This is very similar to the :bufdo
solution mentioned by another commenter, but it will use your args list rather than your buflist (and thus doesn't require a brand new vim session nor for you to be careful about closing buffers you don't want touched).
:args **/*.js
- 将您的 arglist 设置为包含此目录和子目录中的所有 .js 文件|
- 管道是vim的命令分隔符,让我们在一行中有多个命令:argdo
- 对所有参数运行以下命令.它会吞下"后续的管道%
- 代表整个文件的范围:s
- 你已经知道的替代命令:s_flags
,ge
- 全局(每行替换尽可能多的次数)并抑制错误(即不匹配")|
- 这个管道被:argdo
吞没",所以下面的命令也对每个参数运行一次:update
- 与:write
类似,但仅当缓冲区已被修改时
:args **/*.js
- sets your arglist to contain all .js files in this directory and subdirectories|
- pipe is vim's command separator, letting us have multiple commands on one line:argdo
- run the following command(s) on all arguments. it will "swallow" subsequent pipes%
- a range representing the whole file:s
- substitute command, which you already know about:s_flags
,ge
- global (substitute as many times per line as possible) and suppress errors (i.e. "No match")|
- this pipe is "swallowed" by the:argdo
, so the following command also operates once per argument:update
- like:write
but only when the buffer has been modified
这种模式显然适用于您想要在多个文件上运行的任何 vim 命令,因此记住它很方便.例如,我喜欢用它来删除尾随空格(
%s/\s\+$//
),设置统一的行尾(set ff=unix
)或文件编码(set filencoding=utf8
),以及retab
我的文件.This pattern will obviously work for any vim command which you want to run on multiple files, so it's a handy one to keep in mind. For example, I like to use it to remove trailing whitespace (
%s/\s\+$//
), set uniform line-endings (set ff=unix
) or file encoding (set filencoding=utf8
), andretab
my files.这篇关于使用脚本将正则表达式替换全局应用于许多文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!