手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网站运营>建站经验>列表

sed 实例,第 3 部分

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!
Quicken 来结算我的银行帐户。Quicken 是个很好的金融程式,当然会成功地完成这项工作。但是,经过考虑之后,我觉得自己能够轻易编写某个软件来结算我的支票簿。我想,毕竟,我是个软件研发人员!

我研发了一个很好的小型支票簿结算程式(使用 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<数据>  
T<交易量>
N<支票号>
P<描述>
^ (这是字段分隔符)

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

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

 1d /^^/d s/[[:cntrl:]]//g 

第一个 '1d' 命令删除第一行,第二个命令从输出除去那些讨厌的 '^' 字符。最后一行除去文档中可能存在的任何控制字符。既然在处理外来文档格式,我想消除在中途碰到任何控制字符的风险。到现在为止,一切顺利。现在,要向该基本脚本中添加一些处理功能:

 1d /^^/d s/[[:cntrl:]]//g /^D/ { 
s/^D(.*)/1tOUTYtINNYt/
s/^01/Jan/ s/^02/Feb/
s/^03/Mar/ s/^04/Apr/
s/^05/May/ s/^06/Jun/
s/^07/Jul/ s/^08/Aug/
s/^09/Sep/ s/^10/Oct/
s/^11/Nov/ s/^12/Dec/
s:^(.*)/(.*)/(.*):2 1 3: }

首先,添加一个 '/^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/ {
s/^D(.*)/1tOUTYtINNYt/
s/^01/Jan/ s/^02/Feb/
s/^03/Mar/ s/^04/Apr/
s/^05/May/ s/^06/Jun/
s/^07/Jul/ s/^08/Aug/
s/^09/Sep/ s/^10/Oct/
s/^11/Nov/ s/^12/Dec/
s:^(.*)/(.*)/(.*):2 1 3:
N N N
s/nT(.*)nN(.*)nP(.*)/NUM2NUMttYtt3tAMT1AMT/
s/NUMNUM/-/ s/NUM([0-9]*)NUM/1/
s/([0-9]),/1/ }

后七行有些复杂,所以将周详讨论他们。首先,连续使用三个 'N' 命令。'N' 命令告诉 sed 将下一行读入输入中,然后将其附加到当前模式空间。这三个 'N' 命令导致将下三行附加到当前模式空间缓冲区,现在这一行看起来如下:

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!