利⽤find和sed批量替换⽂件内容
这是这个连锁反应:发现apache的log没有分⽇期、分正误记录 --> 改为分⽇期、分正误记录log --> 观察错误log,发现有⼤量404错误 --> 需要修正程序,发现⽂件路径错误 --> 本机使⽤Dreamweaver替换路径,提交SVN --> 部署到服务器上时发现⽂件太多、且分散在⼦⽬录中
怎么办?⼀个⼀个⼀个⼀个上传?傻⼦才⼲!既然是在FreeBSD下,那就是⽤强⼤的命令⾏⼯具吧!实践中发现这个⽅法真的很实⽤,记录下来!
需求:把本⽬录下,包括⼦⽬录下的⽂件,把所有含有“/adm/images/c.gif”的地⽅替换为“/Admin/Images/c.gif”。
步骤:出⽂件,到地⽅,替换。
寻命令:到⽂件(find,ls),到地⽅(grep),替换(sed)。
现在需要做的,就是组合起来。
查资料,有前辈告诫:“find 命令是所有 Linux 命令中最有⽤的⼀个,同时也是最混乱的⼀个”,顿时奔溃。
还好,发现find命令有个叫“-exec”的,很是强⼤:find命令对匹配的⽂件执⾏该参数所给出的shell命令。相应命令的形式
为'command' {} /;,注意{}和/;之间的空格。
个⼈理解:-exec参数中的“{}”是该参数前命令产⽣的结果的⼀个变量。感觉类似管道的作⽤了。
⽽且还可以有多个-exec参数,很是强⼤。基本上grep和sed都可以作为⼦命令在其中运⾏了。
如此⼀来,可以使⽤以下命令列出需要替换的字符串所在的⾏了:
以下是代码⽚段:
find ./ -exec grep "/adm/images/c.gif" '{}' /;
然后再使⽤⼀个-exec参数吧sed包含进来吧。
sed 的⼯作⽅式:
以下是引⽤⽚段:
sed 实⽤⼯具按顺序逐⾏将⽂件读⼊到内存中。然后,它执⾏为该⾏指定的所有操作,并在完成请求的修改之后将该⾏放回到内存中,以将其转储⾄终端。完成了这⼀⾏上的所有操作之后,它读取⽂件的下⼀⾏,然后重复该过程直到它完成该⽂件。默认输出是将每⼀⾏的内容输出到屏幕上。在这⾥,开始涉及到两个重要的因素—⾸先,输出可以被重定向到另⼀⽂件中,以保存变化;
第⼆,源⽂件(默认地)保持不被修改。sed 默认读取整个⽂件并对其中的每⼀⾏进⾏修改。不过,可以按需要将操作限制在指定的⾏上。
注意后⾯提到的源⽂件不会修改,不过sed提供了-i参数,可以做到控制是否可以修改源⽂件。-i参数的描述,Linux和FreeBSD下不太⼀样,后来也发现Linux在命令的使⽤⽅便上的确是要强于FreeBSD的。分述如下:
以下是引⽤⽚段:
FreeBSD 4.7-STABLE下:
-i extension
Edit files in-place, saving backups with the specified extension.
If a zero-length extension is given, no backup will be saved. It
If a zero-length extension is given, no backup will be saved. It
is not recommended to give a zero-length extension when in-place
editing files, as you risk corruption or partial content in situ-
ations where disk space is exhausted, etc.
Linux下:
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)
FreeBSD下说如果-i参数后⾯的后缀如果为0,则不产⽣备份⽂件,结果我试了好⼏次都没有搞定,不得已,使⽤了⼀个备份⽂件来存储源⽂件,然后修改源⽂件:
以下是代码⽚段:
find ./ -exec grep "/adm/images/c.gif" '{}' /; -exec sed -i .bak 's///adm//images//c.gif///Admin//Images//c.gif/g' {} /;
⽐如下⾯的就不⾏,⽼提⽰错误,望知情者指教:
以下是代码⽚段:
find ./ -exec grep "/adm/images/c.gif" '{}' /; -exec sed -i 's///adm//images//c.gif///Admin//Images//c.gif/g' {} /;
Linux下,可以不产⽣备份⽂件直接修改了:
以下是代码⽚段:
find ./ -exec grep "/adm/images/c.gif" '{}' /; -exec sed -i 's///adm//images//c.gif///Admin//Images//c.gif/g' {} /;
当然,需要强调的是:备份还是很重要的!切记切记!
本⽂环境如下:
以下是引⽤⽚段:
FreeBSD:
FreeBSD 4.7-STABLE
Linux:
[root@bsso Admin_bak]# cat /etc/issue
CentOS release 4.1 (Final)
Kernel //r on an //m
[root@bsso Admin_bak]# sed --version
GNU sed version 4.1.2
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,
to the extent permitted by law.
to the extent permitted by law.
另:
1:FreeBSD下如何查看sed的版本呢?
2:⽹上看见资料说,类似下⾯的语句应该是可以达到⽬的,当我在FreeBSD和Linux下都没有运⾏成功
以下是代码⽚段:
sed -i 's///adm//images//c.gif///Admin//Images//c.gif/g' `grep -rf "/adm/images/c.gif"`
参考资料:
以下是引⽤⽚段:
Linux⽂件查命令find,xargs详述
Linux Find 命令精通指南
使⽤ sed 编辑器
linux sed 批量替换多个⽂件中的字符串
>find查命令的使用
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论