2011-06-03 44 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文件的简短样本和替换结果吗?

相关问题