我对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;替换没有任何特殊字符的字符串,但我还没有看到类似于我正在尝试做的示例。
非常感谢任何协助。
谢谢。
答案 0 :(得分:2)
您有三个独立的子问题:
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文件的简短样本和替换结果吗?