2010-07-12 19 views
7

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

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

我也试过这个脚本(在一个单一的文件,用于测试):

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

模式将消除所有Perl/Ruby的样式列表中后面的逗号,让“[A,B, c,]“将出现为”[a,b,c]“,以便满足IE浏览器中的IE浏览器的需求。

该模式在vim中运行得非常好,但是如果我在ex中运行它,根据上面的脚本,它什么也不做。

任何人都可以看到我可能会失踪?

+0

我不太了解vim,但是你可以用notepad ++轻松完成,不需要脚本......或者如果你真的想用vim来做,请看看这个。 http://www.ibrahim-ahmed.com/2008/01/find-and-replace-in-multiple-files-in.html – BrunoLM 2010-07-12 02:20:31

回答

12

你问一个脚本,但你提到你是VIM用户。我倾向于做项目范围内发现和VIM内更换,就像这样:

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

这非常类似于另一个评论提到:bufdo解决方案,但它会使用你的args列表,而不是你的buflist(和因此不需要全新的vim会话,也不需要注意关闭不想触及的缓冲区)。

  • :args **/*.js - 设置您arglist中包含此目录中的所有.js文件和子目录
  • | - 管Vim的命令分隔符,让我们有一个行
  • :argdo多个命令 - 运行下面的命令(所有参数)。它将“吞”后续管
    • % - 替代命令,你已经了解
    • :s_flagsge - - 全球(替代多达每行次数尽可能代表整个文件
    • :s范围)和抑制错误(即“不匹配”)
    • | - 这管子是“吞噬”由:argdo,因此下面的命令还经营每一次争论
    • :update - 像:write但只有当缓冲区已修改

这种模式显然您要对多个文件运行任何Vim命令的工作,所以这是一个方便的一个要牢记。例如,我喜欢用它来删除末尾的空格(%s/\s\+$//),设置统一的行尾(set ff=unix)或文件编码(set filencoding=utf8)和retab我的文件。

+0

非常好!但是,vi会阻塞334个文件吗? – 2010-07-15 20:58:22

+1

我已经完成了1000多个文件,没有问题。它不会尝试同时打开文件,并行运行脚本或类似的东西,所以在argdo完成后缓冲区是不活动的(文件从内存中卸载)(除非您在另一个窗口中打开缓冲区)。通过那么多文件可能需要一段时间。 ;) – 2010-07-16 01:32:20

+2

是的,我昨天试过了,它像冠军一样工作。什么是宝石!谢谢! – 2010-07-16 18:05:56

0

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

搜索,\s*\]]

更换应该为你工作描述列表的类型。

5

1)打开用vim的所有文件:

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

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

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

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

:wall 
:q 

我认为你需要重新检查你的搜索模式,它看起来不正确。我想你应该有\_\s*你应该有\_s*

编辑:您还应该使用:s...命令的/ge选项(我已经添加了上述内容)。

+0

'\ s *'匹配零个或多个空格字符。 – 2010-07-12 22:07:56

+0

'\ s *'仅匹配空格和制表符,我相信这个替换函数会调用'\\ _ s *',它也可以匹配换行符。 – 2010-07-12 22:29:24

0

您可以使用find命令的组合和sed

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

很可能在','和右括号之间会出现换行符。 – 2010-07-12 04:28:05

3

您可以通过在命令行,使他们通过参数+'command'自动化既viex的动作被用作文本过滤器。

在你的情况,下面的命令应该很好地工作:

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