类Unix流编辑器sed在线极速入门

第一个实际脚本将 UNIX 风格的文本转换成 DOS/Windows 格式。您可能知道,基于 DOS/Windows 的文本文件在每一行末尾有一个 CR(回车)和 LF(换行),而 UNIX 文本只有一个换行。有时可能需要将某些 UNIX 文本移至 Windows 系统,该脚本将为您执行必需的格式转换。

我已记不清有多少次在下载一些示例脚本或 C 代码之后,却发现它是 DOS/Windows 格式。虽然很多程序不在乎 DOS/Windows 格式的 CR/LF 文本文件,但是有几个程序却在乎 – 最著名的是 bash,只要一遇到回车,它就会出问题。以下 sed 调用将把 DOS/Windows 格式的文本转换成可信赖的 UNIX 格式:

下面是另一个方便的小脚本。与大多数 Linux 发行版中包括的 “tac” 命令一样,该脚本将反转文件中行的次序。”tac” 这个名称可能会给人以误导,因为 “tac” 不反转行中字符的位置(左和右),而是反转文件中行的位置(上和下)。用 “tac” 处理以下文件:

….将产生以下输出:

可以用以下 sed 脚本达到相同目的:

在查看 QIF 格式之前,先看一下我的 checkbook.txt 格式:

在我的文件中,所有字段都由一个或多个制表符分开,每个交易占据一行。日期之后的下一个字段列出支出类型(如果是收入项,则为 “-“)。第三个字段列出收入类型(如果是支出项,则为 “-“)。然后,是一个支票号字段(如果为空,则还是 “-“),一个交易完成字段(”Y” 或 “N”),一个注释和一个美元金额字段。现在,让我们看一下 QIF 格式。当用文本查看器查看下载的 QIF 文件时,它看起来如下:

浏览过文件之后,不难猜出其格式 – 忽略第一行,其余的格式如下:

在处理象这样重要的 sed 项目时,不要气馁 – sed 允许您将数据逐渐修改成最终形式。在进行当中,可以继续细化 sed 脚本,直到输出与预期的完全一样为止。无需在试第一次时就保证其完全正确。

要开始,首先创建一个名为 “qiftrans.sed” 的文件,然后开始修改数据:

花括号中的第一个命令将把如下行:

变换成:

当然,现在的格式还不完美,但没关系。我们将在进行过程中逐渐细化模式空间的内容。后面 12 行的最后效果是将数据变换成三个字母的格式,最后一行从数据中除去三个斜杠。最后得到这一行:

现在进一步细化:

sed 的模式空间变得很难看 – 需要除去额外的新行,并执行某些附加的格式化。要这样做,将使用替代命令。要匹配的模式为:

“NUM” 替换成 。如您所见,用愚蠢的标记括起支票号允许我们在该字段为空时方便地插入一个 “-“。

最后一行除去数字后的逗号。它把如 “3,231.00” 这样的美元金额转换成我使用的格式 “3231.00”。现在,让我们看一下最终脚本:

最终的”QIF 到文本”脚本

附加的十一行使用替代和一些分支功能来美化输出。首先看一下这行:

该行包含一个格式为 “/regexp/b label” 的分支命令。如果模式空间与规则表达式匹配,sed 将分支到 fixnegs 标号。您应该可以轻易找到该标号,它在代码中为 “:fixnegs”。如果规则表达式不匹配,则以常规方式继续处理下一个命令。

既然您理解该命令本身的工作原理,让我们看一下分支。如果看一下分支规则表达式,将看到它与后面依次跟有 ‘-‘、任意数量的数字、一个 ‘.’、任意数量的数字和 ‘AMT’ 的字符串 ‘AMT’ 匹配。就象我确信您已猜到一样,该规则表达式专门处理负的美元金额。在这之前,用 ‘ATM’ 括起美元金额,以便以后可以轻易找到它。因为规则表达式只与以 ‘-‘ 开始的美元金额匹配,所以,该分支只在恰巧处理借款时才发生。如果正处理贷款,应该将 OUTY 设置成 ‘misc’,将 INNY 设置成 ‘-‘,并且应该除去贷款数量前面的负号。如果跟踪代码的流程,将看到实际情况正是这样。如果不执行分支,则用 ‘-‘ 替换 OUTY,用 ‘inco’ 替换 INNY。完成了!现在输出行是完美的:

如您所见,只要循序渐进地解决问题,使用 sed 转换数据就没有那么难。不要试图使用一个 sed 命令或一下子解决所有问题。相反,要朝着目标逐步进行,并不断改进 sed 脚本,直到其输出正如您希望那样为止。sed 有许多功能,希望您已非常熟悉其内部工作原理并继续努力以进一步掌握它!