查找并替换多个目录中的多个文件的html代码

时间:2011-06-03 04:36:45

标签: shell unix search scripting replace

我对shell脚本有一个非常基本的了解,但我需要做的是需要更复杂的命令。

对于一项任务,我需要在服务器上的index.html文件中查找并替换html代码。这些文件位于多个目录中,具有一致的命名约定。 ([letter] [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)

我在网上和其他地方看过其他的例子,只是显示修改单个目录下的文件的脚本来查找&amp;替换没有任何特殊字符的字符串,但我还没有看到类似于我正在尝试做的示例。

非常感谢任何协助。

谢谢。

2 个答案:

答案 0 :(得分:2)

您有三个独立的子问题:

  1. 替换文件中的文字
  2. 应对特殊字符
  3. 选择要将转换应用于
  4. 的文件

    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

答案 1 :(得分: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替换内容可能并不容易,因此我建议在perl脚本中使用HTML或XML解析库。你能提供实际html文件的简短样本和替换结果吗?