在之前的文章中,我在一个实际用例中展示了流编辑器 Sed 的基本用法。 今天,准备好深入了解 Sed,因为我们将深入了解 sed 执行模型。
这也是一个对所有 Sed 命令进行详尽回顾并深入了解它们的细节和微妙之处的机会。
所以,如果你准备好了,启动一个终端, 下载测试文件 舒适地坐在你的键盘前:我们现在就开始我们的探索!
关于 Sed 的一点理论
sed 执行模型初探
要真正了解 Sed,您必须首先了解工具执行模型。
在处理数据时,Sed 一次读取一行输入并将其存储到所谓的模式空间中。 Sed 的所有转换都适用于模式空间。 转换由命令行或外部 Sed 脚本文件中提供的单字母命令描述。 大多数 Sed 命令前面都可以有一个地址或地址范围,以限制它们的范围。
默认情况下,Sed 在每个处理周期结束时打印模式空间的内容,也就是说,就在用下一行输入覆盖模式空间之前。 我们可以这样总结该模型:
- 尝试将下一个输入行读入模式空间
如果读取成功:
- 按脚本顺序应用地址与当前输入行匹配的所有命令
- 如果 sed 未在安静模式下启动 (
-n
) 打印(可能修改的)模式空间的内容 - 回到1。
由于每行处理后pattern space的内容都会丢失,不适合长期存储。 为此,Sed 有第二个缓冲区,即保持空间。 除非您明确请求,否则 Sed 永远不会从保留空间中清除、放置或获取数据。 我们将在稍后研究交换、获取和保持命令时更深入地研究这一点。
Sed 抽象机
上面解释的模型是您将在许多 Sed 教程中看到的。 确实,理解最基本的 Sed 程序就足够正确了。 但是当你开始深入研究更高级的命令时,你会发现这还不够。 所以,让我们现在尝试更正式一点。
实际上,Sed 可以看作是实现一个 抽象机器 谁的 状态 由三个定义 缓冲区, 二 寄存器和两个 旗帜:
- 三个缓冲区 存储任意长度的文本。 是的:三个! 在基本执行模型中,我们讨论了模式空间和保持空间,但 Sed 有第三个缓冲区:追加队列。 从 Sed 脚本的角度来看,它是一个只写缓冲区,Sed 将在其执行的预定义时刻自动刷新(广义上讲,在从输入读取新行之前,或者就在退出之前)。
- Sed 还维护 两个寄存器:行计数器(LC)保存从输入读取的行数,程序计数器(PC)始终保存下一个要执行的命令的索引(脚本中的“位置”)。 Sed 自动增加 PC 作为其主循环的一部分。 但使用特定命令,脚本也可以直接修改 PC 以跳过或重复部分程序。 这就是使用 Sed 实现循环或条件语句的方式。 更多关于这在下面的专用分支部分。
- 最后 两个标志 可以修改某些 Sed 命令的行为:自动打印标志 (AP) 替换标志 (SF)。 当设置了自动打印标志时,Sed 将在覆盖之前自动打印模式空间的内容(特别是在读取新的输入行之前,但不仅仅是)。 当自动打印标志被清除(“未设置”)时,如果脚本中没有明确的命令,Sed 将永远不会打印模式空间的内容。 您可以通过在“安静模式”下运行 Sed 来清除自动打印标志(使用
-n
命令行选项或使用特殊注释#n
在第一行或脚本上)。 “替换标志”由替换命令设置(s
命令),当它的地址和搜索模式都匹配模式空间的内容时。 替换标志在每个新循环开始时被清除,或者当从输入中读取新行时,或者在进行条件分支之后。 在这里,我们将再次在分支部分详细讨论该主题。
此外,Sed 维护已进入其地址范围的命令列表(更多关于范围地址部分的内容)以及几个用于读取和写入数据的文件句柄。 您将在读写命令描述中找到更多相关信息。
阅读全文
本文的其余部分仅供 LHB Pro 会员使用。 您现在可以以每年 50 美元的价格注册阅读本文的其余部分,并免费访问所有仅限会员的帖子、电子书和视频课程。
订阅
已经有一个帐户?
登入