如何实现文本多行替换
没有mvc设计模式之前,大家都是一个页面一个页面的做网页。
那么一旦需要修改页面的时候工作量就会非常大,使用手工去修改,那几乎是不可能完成的任务。
周末为了替换www.redis.com.cn的统计代码,想出两种方案。
首先是使用sed实现单行字符串替换,比较容易,需要注意的是使用-i参数,可以实现原地替换。
但统计代码是多行文本,而且还有转义字符,如果只用sed恐怕有些难度,如果你有好的思路也可以告诉我。
初级单行替换:
如果是简单的单词替换修改,可以使用sed。
下面的指令完成当前目录下递归查找含有html的文件,并把这些文件里的from_str串换成to_str串
1 |
sed -i 's/from_str/to_str/g' `grep html -rl *` |
多行文本替换:
有一些使用sed和awk的高级方法,不过我没看太明白,也没时间查看手册。
所以用php和shell组合来实现该功能
1.创建替换脚本str_replace.php,内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?php //要替换的字符串 $src = '|<script src="http://s15.cnzz.com/stat.php?id=4175462&web_id=4175462&show=pic" language="JavaScript"></script>'; //替换成的字符串,用到了heredoc来实现多行输入 $to = <<<EOF <div style="display:none"> <script type="text/javascript"> var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://"); document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F26186f7cae71b5d3f1dec4993bdb5273' type='text/javascript'%3E%3C/script%3E")); </script> </div> EOF; if (isset($argv[1])) echo $path = $argv[1],PHP_EOL; else die(); if(strstr($path, "str_replace"))exit; $html = file_get_contents($path); $html = str_replace($src, $to, $html); file_put_contents($path, $html); ?> |
2.执行脚本
1 |
find ./ -type f -exec php str_replace.php {} \; |
3.解释:
这个命令由两部分组成,一个是find,另一个是exec
使用find递归列出目录中的文件,当然也可以使用grep递归列出
1 2 3 4 5 |
## 只列出常规文件 find ./ -type f ## 只列出文件夹 find ./ -type d |
-exec是实现对find的查找结果执行该参数后的指令,exec以分号结束
本例但当中就是递归列出目路中的文件名,并对这些文件执行php str_replace.php
{} 之间没有空格
{} ;之间需要有空格,分号不能少,表示exec指令结束。
'{}',使用{}来表示文件名,也就是find前面处理过程中过滤出来的文件,用于exec后跟的命令进行处理
特别强调,对于不同的系统,直接使用分号可能会有不同的意义, 使用转义符 ''在分号前明确说明。
几个常用的find指令备用:
1.查询所有保护字符串“Hello”的文件
1 |
find / -exec grep 'Hello' {} \; |
2.删除所有临时文件
1 |
find / -name '*.tmp' -exec rm -f {} \; |
3 删除20天以前的文件
1 |
find / -name '*' -ctime +20 -exec rm -f {} \; |
注:+20 表示20天以前