我研发了一个很好的小型支票簿结算程式(使用 awk),他通过分析包含我的任何交易的文本文档的语法来计算余额。略微调整之后,我将其改进,以便能够象 Quicken 那样跟踪不同的贷款和借款类别。但是,我还要添加一个特性。最近,我将帐户转移到一家有联机 Web 帐户界面的银行。有一天,我注意到,这家银行的 Web 站点允许以 Quicken 的 .QIF 格式下载我的帐户信息。我马上觉得,假如能够将该信息转换成文本格式,那就太棒了。
两种格式的故事
在查看 QIF 格式之前,先看一下我的 checkbook.txt 格式:
28 Aug 2000 food - - Y Supermarket 30.94 25 Aug 2000 watr - 103 Y Check 103 52.86 |
在我的文档中,任何字段都由一个或多个制表符分开,每个交易占据一行。日期之后的下一个字段列出支出类型(假如是收入项,则为 "-")。第三个字段列出收入类型(假如是支出项,则为 "-")。然后,是个支票号字段(假如为空,则还是 "-"),一个交易完成字段("Y" 或 "N"),一个注释和一个美元金额字段。现在,让我们看一下 QIF 格式。当用文本查看器查看下载的 QIF 文档时,他看起来如下:
!Type:Bank D08/28/2000 T-8.15 N PCHECKCARD SUPERMARKET ^ D08/28/2000 T-8.25 N PCHECKCARD PUNJAB RESTAURANT ^ D08/28/2000 T-17.17 N PCHECKCARD SUPERMARKET |
浏览过文档之后,不难猜出其格式 -- 忽略第一行,其余的格式如下:
D<数据> |
开始处理
在处理象这样重要的 sed 项目时,不要气馁 -- sed 允许您将数据逐渐修改成最终形式。在进行当中,能够继续细化 sed 脚本,直到输出和预期的完全相同为止。无需在试第一次时就确保其完全正确。
要开始,首先创建一个名为 "qiftrans.sed" 的文档,然后开始修改数据:
1d /^^/d s/[[:cntrl:]]//g |
第一个 '1d' 命令删除第一行,第二个命令从输出除去那些讨厌的 '^' 字符。最后一行除去文档中可能存在的任何控制字符。既然在处理外来文档格式,我想消除在中途碰到任何控制字符的风险。到现在为止,一切顺利。现在,要向该基本脚本中添加一些处理功能:
1d /^^/d s/[[:cntrl:]]//g /^D/ { |
首先,添加一个 '/^D/' 地址,以便 sed 只在碰到 QIF 数据字段的第一个字符 'D' 时才开始处理。当 sed 将这样一行读入其模式空间时,将按顺序执行花括号中的任何命令。
花括号中的第一个命令将把如下行:
D08/28/2000 |
变换成:
08/28/2000 OUTY INNY |
当然,现在的格式还不完美,但没关系。我们将在进行过程中逐渐细化模式空间的内容。后面 12 行的最后效果是将数据变换成三个字母的格式,最后一行从数据中除去三个斜杠。最后得到这一行:
Aug 28 2000 OUTY INNY |
OUTY 和 INNY 字段是占位符,以后将被替换。现在还不能确定他们,因为假如美元金额为负,将把 OUTY 和 INNY 配置成 "misc" 和 "-",但是,假如美元金额为正,将分别把他们更改成 "-" 和 "inco"。既然还没有读入美元金额,所以,需要暂时使用占位符。
细化
现在进一步细化:
1d /^^/d s/[[:cntrl:]]//g /^D/ { |
后七行有些复杂,所以将周详讨论他们。首先,连续使用三个 'N' 命令。'N' 命令告诉 sed 将下一行读入输入中,然后将其附加到当前模式空间。这三个 'N' 命令导致将下三行附加到当前模式空间缓冲区,现在这一行看起来如下:
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




