在本文章系列中,DanIEl Robbins 将为您演示如何使用功能十分强大(但常被遗忘)的 Unix 流编辑器 sed 。sed 是用批处理方式编辑文件或以十分有效的方式创建 shell 脚本以修改现有文件的理想工具 。
挑选编辑器
在 UNIX 世界中有很多文本编辑器可供我们选择 。思考一下 -- vi、eMacs 和 jed 以及很多其它工具都会浮现在脑海中 。我们都有自己已逐渐了解并且喜爱的编辑器(以及我们喜爱的组合键) 。有了可信赖的编辑器,我们可以轻松处理任何数量与 UNIX 有关的管理或编程任务 。虽然交互式编辑器很棒,但却有其限制 。尽管其交互式特性可以成为强项,但也有其不足之处 。考虑一下需要对一组文件执行类似更改的情形 。您可能会本能地运行自己所喜爱的编辑器,然后手工执行一组烦琐、重复和耗时的编辑任务 。然而,有一种更好的方法 。进入 sed
如果可以使编辑文件的过程自动化,以便用“批处理”方式编辑文件,甚至编写可以对现有文件进行复杂更改的脚本,那将太好了 。幸运的是,对于这种情况,有一种更好的方法 -- 这种更好的方法称为 "sed" 。sed 是一种几乎包括在所有 UNIX 平台(包括 Linux)的轻量级流编辑器 。sed 有许多很好的特性 。首先,它相当小巧,通常要比您所喜爱的脚本语言小很多倍 。其次,因为 sed 是一种流编辑器,所以,它可以对从如管道这样的标准输入接收的数据进行编辑 。因此,无需将要编辑的数据存储在磁盘上的文件中 。因为可以轻易将数据管道输出到 sed,所以,将 sed 用作强大的 shell 脚本中长而复杂的管道很容易 。试一下用您所喜爱的编辑器去那样做 。GNU sed
对 Linux 用户来说幸运的是,最好的 sed 版本之一恰好是 GNU sed,其当前版本是 3.02 。每一个 Linux 发行版都有(或至少应该有)GNU sed 。GNU sed 之所以流行不仅因为可以自由分发其源代码,还因为它恰巧有许多对 POSIX sed 标准便利、省时的扩展 。另外,GNU 没有 sed 早期专门版本的很多限制,如行长度限制 -- GNU 可以轻松处理任意长度的行 。最新的 GNU sed
在研究这篇文章之时我注意到:几个在线 sed 爱好者提到 GNU sed 3.02a 。奇怪的是,在ftp.gnu.org(有关这些链接,请参阅参考资料)上找不到 sed 3.02a,所以,我只得在别处寻找 。我在alpha.gnu.org 的 /pub/sed 中找到了它 。于是我高兴地将其下载、编译然后安装,而几分钟后我发现最新的 sed 版本却是 3.02.80 -- 可在alpha.gnu.org 上 3.02a 源代码旁边找到其源代码 。安装完 GNU sed 3.02.80 之后,我就完全准备好了 。
正确的 sed
在本系列中,将使用 GNU sed 3.02.80 。在即将出现的本系列后续文章中,某些(但非常少)最高级的示例将不能在 GNU sed 3.02 或 3.02a 中使用 。如果您使用的不是 GNU sed,那么结果可能会不同 。现在为什么不花些时间安装 GNU sed 3.02.80 呢?那样,不仅可以为本系列的余下部分作好准备,而且还可以使用可能是目前最好的 sed 。sed 示例
sed 通过对输入数据执行任意数量用户指定的编辑操作(“命令”)来工作 。sed 是基于行的,因此按顺序对每一行执行命令 。然后,sed 将其结果写入标准输出 (stdout),它不修改任何输入文件 。让我们看一些示例 。头几个会有些奇怪,因为我要用它们演示 sed 如何工作,而不是执行任何有用的任务 。然而,如果您是 sed 新手,那么理解它们是十分重要的 。下面是第一个示例:
$ sed -e "d" /etc/services如果输入该命令,将得不到任何输出 。那么,发生了什么?在该例中,用一个编辑命令 "d" 调用 sed 。sed 打开 /etc/services 文件,将一行读入其模式缓冲区,执行编辑命令(“删除行”),然后打印模式缓冲区(缓冲区已为空) 。然后,它对后面的每一行重复这些步骤 。这不会产生输出,因为 "d" 命令除去了模式缓冲区中的每一行!在该例中,还有几件事要注意 。首先,根本没有修改 /etc/services 。这还是因为 sed 只读取在命令行指定的文件,将其用作输入 -- 它不试图修改该文件 。第二件要注意的事是 sed 是面向行的 。"d" 命令不是简单地告诉 sed 一下子删除所有输入数据 。相反,sed 逐行将 /etc/services 的每一行读入其称为模式缓冲区的内部缓冲区 。一旦将一行读入模式缓冲区,它就执行 "d" 命令,然后打印模式缓冲区的内容(在本例中没有内容) 。我将在后面为您演示如何使用地址范围来控制将命令应用到哪些行 -- 但是,如果不使用地址,命令将应用到所有行 。第三件要注意的事是括起 "d" 命令的单引号的用法 。养成使用单引号来括起 sed 命令的习惯是个好注意,这样可以禁用 shell 扩展 。另一个 sed 示例
推荐阅读
- 通用线程--sed 实例,第2部分
- FreeBSD下设置modem和modem的通用命令
- 什么叫多线程
- 和彩云支持普通用户上传多大文件
- 缝好衣服后怎么用短线快速打结?男女通用
- 医保是全国通用的吗
- 5e和steam皮肤通用吗
- 下 Solaris 10通用桌面CDE快速入门
- 中 Solaris 10通用桌面CDE快速入门
- 4 Solaris 8 新增功能一览--通用磁盘格式 (UDF) 文件系统