2010-07-12 35 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!'