2011-06-03 71 views
2

我對shell腳本有一個非常基本的理解,但是我需要做的事情需要更復雜的命令。在多個目錄中查找並替換多個文件的html代碼

對於一項任務,我需要在我的服務器上的index.html文件中查找並替換html代碼。這些文件位於多個具有一致命名約定的目錄中。 ([字母] [3位數字])請參閱下面的示例。

files: index.html 
path: /www/mysite/board/today/[rsh][0-9]/ 
string to find: (div id="id")[code](/div)<--#include="(path)"-->(div id="id")[more code](/div) 
string to replace with: (div id="id")<--include="(path)"-->(/div) 

我希望你不要介意僞正則表達式。包含我的目標index.html文件的文件夾看起來類似於r099,s017,h123。並且足以說明,我試圖替換的html代碼相對較長,但它仍然只是一個字符串。

第二個任務與第一個任務類似,只有文件名也會更改。

files: [rsh][0-9].html 
path: www/mysite/person/[0-9]/[0-9]/[0-9]/card/2011/ 
string: (div id="id")[code](/div)<--include="(path)"-->(div id="id")[more code](/div) 
string to replace with: (div id="id")<--include="(path)"-->(/div) 

我見過的其他例子在SO和在網上簡單地展示腳本修改一個目錄下的文件找到&替換字符串沒有任何特殊字符的其他地方,但我還沒有看到類似的例子到我正在嘗試做的事情。

任何援助將不勝感激。

謝謝。

回答

2

你有三個獨立的子問題:

  1. 有特殊字符
  2. 選擇文件替換文件
  3. 應對文本的轉換應用於

1。該規範的文本替換工具sed

sed -e 's/PATTERN/REPLACEMENT/g' <INPUT_FILE >OUTPUT_FILE 

如果您GNU的sed(例如Linux或Cygwin的),通過-i轉換文件中的位置。您可以在同一命令行中處理多個文件。

sed -i -e 's/PATTERN/REPLACEMENT/g' FILE OTHER_FILE… 

如果您的sed沒有-i選項,你需要寫一個不同的文件並移動到位之後。 (這是GNU sed在幕後做的)。

sed -e 's/PATTERN/REPLACEMENT/g' <FILE >FILE.tmp 
mv FILE.tmp FILE 

2。如果要用文字字符串替換文字字符串,則需要在所有特殊字符前加一個反斜槓。對於sed模式,特殊字符爲.\[^$*加上s命令的分隔符(通常爲/)。對於sed替換文本,特殊字符爲\&和換行符。您可以使用sed將字符串轉換爲合適的圖案或替換文字。

pattern=$(printf %s "$string_to_replace" | sed -e 's![.\[^$*/]!\\&!g') 
replacement=$(printf %s "$replacement_string" | sed -e 's![\&]!\\&!g') 

3。要直接在一個或多個目錄中處理多個文件,請使用shell通配符。你的要求似乎並不完全一致;我認爲這些是你正在尋找的模式,但一定要檢查它們。

/www/mysite/board/today/[rsh][0-9][0-9][0-9]/index.html 
/www/mysite/person/[0-9]/[0-9]/[0-9]/card/2011/[rsh][0-9].html 

這會匹配/www/mysite/board/today/r012/index.html/www/mysite/person/4/5/6/card/2011/h7.html,但不/www/mysite/board/today/subdir/s012/index.html/www/mysite/board/today/r1234/index.html文件。

如果您需要以遞歸方式處理子目錄中的文件,請使用find。它似乎不符合你的要求,這個答案已經足夠長了,所以我會在這裏停下來。

4。把它放在一起:

string_to_replace='(div id="id")[code](/div)<--#include="(path)"-->(div id="id")[more code](/div)' 
replacement_string='(div id="id")<--include="(path)"-->(/div)' 
pattern=$(printf %s "$string_to_replace" | sed -e 's![.\[^$*/]!\\&!g') 
replacement=$(printf %s "$replacement_string" | sed -e 's![\&]!\\&!g') 
sed -i -e "s/$pattern/$replacement/g" \ 
    /www/mysite/board/today/[rsh][0-9][0-9][0-9]/index.html \ 
    /www/mysite/person/[0-9]/[0-9]/[0-9]/card/2011/[rsh][0-9].html 

最後說明:你似乎正在使用正則表達式的HTML。那是often not a good idea

0

查找文件,可以很容易地使用find -regex來完成:

find www/mysite/board/today -regex ".*[rsh][0-9][0-9][0-9]/index.html" 
find www/mysite/person -regex ".*[0-9]/[0-9]/[0-9]/card/2011/[rsh][0-9][0-9][0-9].html" 

由於HTML的性質,更換內容可能並不十分容易sed,所以我會建議使用HTML或XML解析庫一個Perl腳本。你能提供一個實際html文件的簡短樣本和替換結果嗎?