使用脚本将正则表达式替换全局应用于许多文件

时间:2010-07-12 02:14:21

标签: regex vim scripting replace

我想将一个正则表达式替换全局应用于目录中和目录下的大约40个Javascript文件。我是一个vim用户,但手动执行此操作可能会很乏味且容易出错,所以我想用脚本自动执行它。

我试过sed,但是一次处理多行是很尴尬的,特别是如果模式可能匹配的行数没有限制。

我也试过这个脚本(在一个文件上进行测试):

ex $1 <<EOF
gs/,\(\_\s*[\]})]\)/\1/
EOF

该模式将消除任何Perl / Ruby样式列表中的尾随逗号,因此“[a,b,c,]”将显示为“[a,b,c]”以满足Internet Explorer ,仅在浏览器中,就会在这些列表上窒息。

该模式在vim中运行得非常漂亮,但如果我在ex中运行它,则不会执行任何操作,如上面的脚本所示。

任何人都可以看到我可能缺少的东西吗?

5 个答案:

答案 0 :(得分:12)

您要求提供脚本,但您提到您是vim用户。我倾向于在vim内部进行项目范围内的查找和替换,如下所示:

:args **/*.js | argdo %s/,\(\_\s*[\]})]\)/\1/ge | update

这与其他评论者提到的:bufdo解决方案非常相似,但它会使用你的args列表而不是你的buflist(因此不需要全新的vim会话,也不需要你注意关闭你不想触摸的缓冲区。)

  • :args **/*.js - 将您的arglist设置为包含此目录和子目录中的所有.js文件
  • | - pipe是vim的命令分隔符,让我们在一行上有多个命令
  • :argdo - 对所有参数运行以下命令。它将“吞下”后续的管道
    • % - 表示整个文件的范围
    • :s - 替换命令,您已经了解
    • :s_flagsge - 全局(尽可能多替换每行)并抑制错误(即“不匹配”)
    • | - :argdo“吞下”此管道,因此以下命令每个参数也会运行一次
    • :update - 与:write类似,但仅限于缓冲区已修改

这个模式显然适用于你想在多个文件上运行的任何vim命令,所以要记住它是一个方便的。例如,我喜欢用它来删除尾随空格(%s/\s\+$//),设置统一的行尾(set ff=unix)或文件编码(set filencoding=utf8)和retab我的文件。

答案 1 :(得分:5)

1)用vim打开所有文件:

bash$ vim $(find . -name '*.js')

2)对所有文件应用替换命令:

:bufdo %s/,\(\_\s*[\]})]\)/\1/ge

3)保存所有文件并退出:

:wall
:q

我认为你需要重新检查你的搜索模式,看起来不对。我认为您应该\_\s*取代\_s*

修改:您还应该使用/ge命令的:s...选项(我已在上面添加了这些选项)。

答案 2 :(得分:3)

您可以通过从命令行传递参数vi来自动执行ex+'command'的操作,这样就可以将它们用作文本过滤器。

在您的情况下,以下命令应该可以正常工作:

  

find /path/to/dir -name '*.js' | xargs ex +'%s/,\(\_\s*[\]})]\)/\1/g' +'wq!'

答案 3 :(得分:1)

您可以结合使用find命令和sed

find /path -type f -iname "*.js" -exec sed -i.bak 's/,[ \t]*]/]/' "{}" +;

答案 4 :(得分:0)

如果你在Windows上,Notepad ++允许你在所有打开的文件上运行简单的正则表达式。

搜索,\s*\]并替换为]

应该适用于您描述的列表类型。