3.3. Awk 源自 Sed 和 Grep,最终源自 Ed —— 第二部分

未匹配的标注

Awk 源自 Sed 和 Grep,最终源自 Ed —— 第二部分

grep 的起源

我们熟悉的 UNIX 使用程序 grep 来源于 ed 中的下面这个全局命令:

​ g/re/p

代表 “global regular expression print”(全局的正则表达式打印)。

Grep 是一个从 ed 里面提取出来的行编辑工具并被作为一个外部程序。它是固定(hard-wired)的执行一个编辑命令。它接收正则表达式作为一个命令行参数,并将它作为要打印的行的地址。比如,寻找查找匹配 box 的行:image-20221015155755137

打印出匹配正则表达式的所有行。

ed 的可编程特性

Ed 一个有趣的特性是用脚本进行编辑的能力。将这些脚本放进一个独立的文件,作为行编辑器的输入。比如,如果一系列的命令放在一个名为 ed-script 的文件中,下面的命令执行这个脚本:

ed test < ed-script

这个特性使得 ed 成为一个可编程的编辑器——也就是说你可以用脚本编写任何你可能手动执行的动作。

Sed vs ed

Sed 被作为一个特殊的专门为了执行脚本的编辑器而被创造出来。 它不像 ed ,不能被交互地使用。 sed 与 ed 主要差异在它是面向流的。默认情况下,传给 sed 的所有输入都直接通过并到达标准输出。输入文件本身是不能更改的。如果你真的想修改输入文件,通常你可以使用 shell 的输出重定向机制。当你对你的修改满意时,使用修改版本替换原来的文件。

ed 不是面向流的,修改会作用于文件本身。一个 ed 脚本必须包含保存文件,退出编辑器的命令。除了某些可能被特定命令产生的输出以外,它在屏幕上不产生任何输出。

sed 的面向流特性对它是怎么寻址的有很大的影响。在 ed 里面,没有地址的一个命令只影响当前行。而 sed 是遍历整个文件,每次处理一行,因此每一行都会变成当前行,这样这个命令就会被应用到每一行。结果是对一个没有地址的命令, sed 会将此命令应用在文件当中的每一行。看下面这个替换命令。

s/regular/complex/

如果你在 ed 里面交互式的键入这个命令,你将替换当前行的第一个 regular 匹配为 “complex”。 在一个 ed 脚本里,如果这是脚本里的第一个命令,它将会只应用在文件的最后一行(也就是 ed 的当前行)。在一个 sed 脚本里,同样的命令应用于所有行。也就是说,sed 命令是隐式全局的。在 sed 里面,前面的例子和下面在 ed 里的全局命令异曲同工:

g/regular/s//complex/

注意:理解 ed 里面的当前行寻址和 sed 里面的全局行寻址的区别是很重要的。在 ed 里面,你使用地址去扩展一个命令影响的行数,而在 sed 里面,你使用地址去限制一个命令影响的行数。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 查看所有版本


暂无话题~