笔记 by 车东

用sed批量替换文件中的字符

· 技术笔记|Tech Notes

由于缺乏模板系统,以前使用html编写的笔记已经很久没有更新了,如果需要对页面内容进行一些更新(比如要更换一下页面中的CSS文件路径),可以用sed完成。对于多个文件的批量处理,整理步骤如下:

1 先创建一个temp目录,将需要更新的文件放到这个临时目录工作下: cp *.html temp/ 2 用ll + awk组合生成脚本文件: ls -1 * | awk ‘{print “sed s#/style.css#/blog/styles_zh-cn.css#g “$1” > ../"$1}’ > sed.sh 生成后的脚本文件如下:

sed s#/style.css#/blog/styles_zh-cn.css#g acdsee.html > ../acdsee.html sed s#/style.css#/blog/styles_zh-cn.css#g ant.html > ../ant.html sed s#/style.css#/blog/styles_zh-cn.css#g apache_install.html > ../apache_install.html sed s#/style.css#/blog/styles_zh-cn.css#g awstats.html > ../awstats.html sed s#/style.css#/blog/styles_zh-cn.css#g cache.html > ../cache.html sed s#/style.css#/blog/styles_zh-cn.css#g click.html > ../click.html sed s#/style.css#/blog/styles_zh-cn.css#g cms.html > ../cms.html sed s#/style.css#/blog/styles_zh-cn.css#g comment.html > ../comment.html sed s#/style.css#/blog/styles_zh-cn.css#g compress.html > ../compress.html sed s#/style.css#/blog/styles_zh-cn.css#g cvs_card.html > ../cvs_card.html sed s#/style.css#/blog/styles_zh-cn.css#g default.html > ../default.html sed s#/style.css#/blog/styles_zh-cn.css#g dev.html > ../dev.html sed s#/style.css#/blog/styles_zh-cn.css#g gnu.html > ../gnu.html sed s#/style.css#/blog/styles_zh-cn.css#g google_ads.html > ../google_ads.html sed s#/style.css#/blog/styles_zh-cn.css#g google.html > ../google.html sed s#/style.css#/blog/styles_zh-cn.css#g google_url.html > ../google_url.html sed s#/style.css#/blog/styles_zh-cn.css#g hello_unicode.html > ../hello_unicode.html sed s#/style.css#/blog/styles_zh-cn.css#g indent_tools.html > ../indent_tools.html sed s#/style.css#/blog/styles_zh-cn.css#g index.html > ../index.html sed s#/style.css#/blog/styles_zh-cn.css#g link_pop_check.html > ../link_pop_check.html sed s#/style.css#/blog/styles_zh-cn.css#g lucene.html > ../lucene.html sed s#/style.css#/blog/styles_zh-cn.css#g mysql.html > ../mysql.html sed s#/style.css#/blog/styles_zh-cn.css#g nat.html > ../nat.html sed s#/style.css#/blog/styles_zh-cn.css#g oe2html.html > ../oe2html.html sed s#/style.css#/blog/styles_zh-cn.css#g oracle.html > ../oracle.html sed s#/style.css#/blog/styles_zh-cn.css#g resin.html > ../resin.html sed s#/style.css#/blog/styles_zh-cn.css#g rotate_merge_log.html > ../rotate_merge_log.html sed s#/style.css#/blog/styles_zh-cn.css#g sed.sh > ../sed.sh sed s#/style.css#/blog/styles_zh-cn.css#g study.html > ../study.html sed s#/style.css#/blog/styles_zh-cn.css#g unicode_java.html > ../unicode_java.html sed s#/style.css#/blog/styles_zh-cn.css#g weblog.html > ../weblog.html sed s#/style.css#/blog/styles_zh-cn.css#g weblucene.html > ../weblucene.html sed s#/style.css#/blog/styles_zh-cn.css#g xml_potato.html > ../xml_potato.html sed s#/style.css#/blog/styles_zh-cn.css#g xslt.html > ../xslt.html

3 然后执行脚本文件: shell sed.sh

很多时候批量数据的处理,都可以先做好单个命令,然后通过awk(甚至Excel)登生成批处理脚本。然后用生成的脚本(shell 或SQL)批量执行。

JieEr提供了一个更简便的方法:

[sed](http://www.chedong.com/blog/archives/001091.html) -in-place -e 's/abc/cba/g' *
-i[SUFFIX], --in-place[=SUFFIX] edit files in place (makes backup if extension supplied)

💬 历史评论

以下 13 条评论从旧版 Movable Type 博客迁移而来。 原始评论时间:2002–2016 年。

RainX · 2006-09-17 11:31

呵呵,不错,我觉得批量修改文件还是 perl -pi -e “regex“ 这种方式方便, 和find 结合还可以支持多级的子目录下文件内容的替换.

这个是我之前的一篇blog http://rainx.cn/archives/81


BunnyQ · 2006-09-17 13:07

恩,比较习惯用sed替换字符串了。


jieer · 2006-09-17 19:59

sed -in-place -e ’s/abc/cba/g’ *

回复jie’er: 谢谢! 这个方法更简便


hightman · 2006-09-18 00:26

一条小程序也行, 各行之间用 ; 连接成一行亦可以…

for f in ls *.html do cat $f | sed s#/style.css#/blog/styles_zh-cn.css#g > tmp.txt mv -f tmp.txt $f done


jick · 2006-09-18 13:34

受教了!

顺便问个问题:怎么替换多行?

如将 “line1 line2 …”

替换为

“line3 …”

谢谢!


路杨 · 2006-09-20 22:33

可以用Perl写个脚本分析成MT能认识的纯文本,然后导入MT的MySQL。这样好管理。


momo · 2006-09-21 10:24

不错,就是怕同时替换多个文件中的内容会不会因为逻辑失误造成大面积替换错误。我也希望用这个办法同时修改大批模版文件,批量改模版的工作太累人了。


过客 · 2007-05-11 16:48

–in-place 好像不是所有的平台都支持。。。 我在Solaris 10上就不能用

RainX 提供的方法比较好


过客 · 2007-05-11 16:52

jick: 我在网上搜到了这个,参照 “Pattern Matching Across More than 1 Line”

http://pegasus.rutgers.edu/~elflord/unix/sed.html


piner · 2007-09-19 17:59

我也提供一个perl的解决方案,不用害怕跨平台了。

perl -e ’s#/u01/data_archvie#/u02/logs/admin#i’ -pi.bak (find . -type f )


老甘 · 2008-08-08 16:55

grep和sed配合 sed -i “s/Linux/Linuxidc/g” grep Linux -rl /home/dir


apa · 2008-09-01 11:35

这种方法有问题,lz, 不知道你有没有试过这个方法, 你直接用 > 从定向到原来的文件,sed是流操作,等于原来的文件被清空了,如果不行你可以试试,。应该加个参数吧,我记不清楚了,好像试 -i,直接修改源文件


魏志锋 · 2008-11-21 17:59

车大 你的文章都是很实用 一语中的的 佩服下