关于使用正则表达式在多个文件中跨行替换的问题。

2019-01-20 11:47:48 +08:00
 shayuvpn0001

接手一个老 ASP 项目,很老的那种 ASP 项目,引用了一批 js 和 css 文件,几百个 html 和 asp 混写的文件,没有把这些引用分离出去作为一个公用的 header,现在的问题是,原来他们引用的 js 和 css 文件服务器有一些要关闭了,所以干脆全部切换到自己的新服务器上。需要批量替换掉下面这种格式:

<!---------------------------------------------------------------------->
<!-- Glass theme CSS files, added by Jeff Mills, on April 16th, 2001 -->
<link rel="stylesheet" type="text/css" href="http://www.abc.com/static/glass_theme.css">
<!-- Dynamic Hue effect CSS files, added by Tom Brooks, on 05/12/2005 -->
<link rel="stylesheet" type="text/css" href="http://www.def.com/include/css/dn.1.2.0.css">
<!-- jQuery files, added by Mark Williams, on Jan. 27th, 2009 -->
<!-- jQuery files, updated by Mark Williams, on Oct. 18th, 2010 -->
<script src="http://www.jkl.uk/js/jquery.min.js"></script>

先开始是想如果能够在原来注释下面继续修改并添加自己的就更好了,比如这样

<!---------------------------------------------------------------------->
<!-- Glass theme CSS files, added by Jeff Mills, on April 16th, 2001 -->
<!-- Glass theme CSS files, updated by Y. Sha, on Jan. 18th, 2019 -->
<link rel="stylesheet" type="text/css" href="http://www.newsvr.com/static/css/glass_theme.1.1.0.css">
<!-- Dynamic Hue effect CSS files, added by Tom Brooks, on 05/12/2005 -->
<!-- Dynamic Hue effect CSS files, updated by Y. Sha, on Jan. 18th, 2019 -->
<link rel="stylesheet" type="text/css" href="http://www.newsvr.com/static/css/dn.1.2.0.css">
<!-- jQuery files, added by Mark Williams, on Jan. 27th, 2009 -->
<!-- jQuery files, updated by Mark Williams, on Oct. 18th, 2010 -->
<!-- jQuery files, updated by Y. Sha, on Jan. 18th, 2019 -->
<script src="http://www.newsvr.com/static/js/jquery.min.1.4.2.js"></script>

我发现这样很麻烦,所以先把这个整体替换掉让项目能用,以后有时间再慢慢琢磨。

所以决定干脆把这些统一替换成自己的:

<!---------------------------------------------------------------------->
<!-- Glass theme CSS files, updated by Y. Sha, on Jan. 18th, 2019 -->
<link rel="stylesheet" type="text/css" href="http://www.newsvr.com/static/css/glass_theme.1.1.0.css">
<!-- Dynamic Hue effect CSS files, updated by Y. Sha, on Jan. 18th, 2019 -->
<link rel="stylesheet" type="text/css" href="http://www.newsvr.com/static/css/dn.1.2.0.css">
<!-- jQuery files, updated by Y. Sha, on Jan. 18th, 2019 -->
<script src="http://www.newsvr.com/static/js/jquery.min.1.4.2.js"></script>

我用 grep -Pzo 使用 perl 格式的 pattern 可以找到这些内容,但是用 sed 去替换的时候就出现了问题。我对 sed 不熟,好象是 perl 格式写的正则无法直接在 sed 中使用。 以前经常用的多个文件单行内替换是这样操作的。

grep 'pattern_old' -rl ./ | xargs sed -i "s/pattern_old/pattern_new/g"

这条命令只适合多个文件的一行内使用,跨行就不行了,想请各位帮我参考一下,这个 sed 应该怎么写?

2004 次点击
所在节点    程序员
8 条回复
hcymk2
2019-01-20 13:30:18 +08:00
DOM 建议用 DOM 工具来操作。
AX5N
2019-01-20 13:44:59 +08:00
如果你只是改个 url 的话,单行多替换几次不也一样吗。
ltux
2019-01-20 14:41:08 +08:00
何不直接用 perl
perl -p -0777 -e 's/old/new/g' FILE_PATH
这结果会输出到终端,确认没问题了就加个 -i 选项完成文件替换
perl -p -i -0777 -e 's/old/new/g' FILE_PATH
1OF7G
2019-01-20 15:36:41 +08:00
这是 Commit Log 写在注释里的节奏?不用 Git 之类的吗
shayuvpn0001
2019-01-20 16:18:43 +08:00
@1OF7G 上个世纪的项目,你不能要求太高。

@ltux 我刚在 stackoverflow 上看到了一个类似的解法,好像 sed 确实是不好弄,目前正在试 perl。
alcarl
2019-01-20 17:07:16 +08:00
3 楼的方法应该可行,改一下正则试试吧
ltux
2019-01-20 19:17:28 +08:00
如果你用了元字符 . 并希望他能匹配换行符,则需要 /s 开关,即 dotall 模式。
选项 -0777 的意思是一次性读入整个文件。无此选项则一次读一行,你的替换操作也仅限于此行。
vincentxue
2019-01-21 13:36:09 +08:00
你点我资料看一下我开源那个正则项目里有 sed 和 awk 的正则,和首页的那些 pcre 的对比一下就知道区别了,主要就是转义和一些高级语法支持的问题。sed 用的是 posix 标准,和 pcre 不兼容的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/528764

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX