2.2. 你可以解决有趣的问题吗?

未匹配的标注

你可以解决有趣的问题吗?

学习 sed 和 awk 的主要动力是他们有助于设计文本编辑问题的通用解决方案。对于一些人来讲,包括我自己,工作和苦役的不同在于解决问题的满足感。要你选择使用 vi 或 sed 来对大量的文件进行一系列的重复编辑,我选择使用sed,仅仅是因为这使我对这个问题更感兴趣。我在完善一个解决方法,而不是重复的敲键盘。另外一旦我完成了我的任务,我会庆幸自己很聪明。我觉得自己好像使了一点魔法,并免除了自己的一些枯燥活儿。

一开始,使用 sed 和 awk 来完成一项任务是任重而道远的。在几次尝试之后,你可能会得出结论,手动来做这个工作可能更容易。耐心一点,你不仅仅需要学习如何使用 sed 和 awk, 你还需要学习识别在什么情况下使用它们。随着你更加熟练,你会更快地解决问题,解决更大范围的问题。

你还将开始看到解决具体问题的一般办法的机会。有一种看待一个问题的办法,然后你就能将它和一类问题联系起来。然后你就能设计一个能被在许多场景里面重用的方法。

让我给你一个例子——不用显示任何代码。我们的书使用了一个交叉引用命名方案,在里面引用是被我们的格式化软件(sqtroff)定义和处理的。在一个文本文档里,一个关于错误处理的章节引用可能写成下面这样的代码:

\*[CHerrorhand]

"CHerrorhand" 是引用名,"\*[" 和 "]" 被称为序列,用来区别引用和其他文本。在一个中央文件里,用于文档中交叉引用的名称被定义为 sqtroff 字符串。比如 "CHerrorhand" 被定义为 "第16章 错误处理" (像这样使用符号交叉引用而非明确引用的方案的优点是如果章节被增加、删除或者重新排序,要反映新的文档的组织结构,只需要编辑中央文件)。当格式化软件处理这个文档时,引用被恰当地处理和扩展。

我们面临的问题是,我们不得不使用同样的文件来创建书籍的一个在线版本,因为我们的 sqtroff 格式化软件只能在本地使用,我们需要某种方法来扩展文件里的交叉引用。换句话说,我们不想要文件包含 "\*[CHerrorhand]",我们想要的是 "CHerrorhand" 引用的实际内容。

有三种可能的办法来解决这个问题。

  1. 使用一个文本编辑器搜索所有的引用,然后将它们一个一个地替换为合适的实际字符串。

  2. 使用 sed 来进行编辑,这类似于手动编辑,只是要快一点。

  3. 使用 awk 写一个程序,分成三个步骤:

    a. 读取中央文档,创造一个引用名称和其定义的列表;

    b. 读取文档,搜索引用调用序列;

    c. 查找列表上的引用名称并将其替换为其定义。

第一个方法明显很耗时,而且不是很有趣。第二个方法使用 sed,它的优点在于创建了一个工具去做这个工作。写一个 sed 脚本去查找这个 "\*[CHerrorhand]" 然后把它替换为 "第16章 错误处理" 是很简单的。同样的脚本可以用修改文档中的每一个文件。但是这个替换的缺点在于它是硬编码的。也就是说对于每个交叉引用,你都需要写一个命令来进行替换。第三个方法,使用 awk 创建一个工具,能够适用于任何遵守这个语法的交叉引用。这个脚本也能被用来扩展在其他书里面的交叉引用,它让你不用编写一个具体替换的列表。它是这三个方法里面最通用的一种,设计的目的是尽可能地将其作为工具重用。

解决问题的一部分是知道要构建哪种工具。有时使用 sed 会是一个更好的选择。因为这个问题还不需要一个更复杂的 awk 脚本,必须记住什么样的应用程序最适合 sed 和 awk。

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

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


暂无话题~