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

sed 实例,第 3 部分

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

 28 Aug 2000	OUTY	INNY	nT-8.15nNnPCHECKCARD SUPERMARKET 

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

 'nT.*nN.*nP.*' 

这将和后面依次跟有 'T'、零或多个字符、新行、'N'、任何数量的字符、新行、'P'、连同任何数量字符的新行匹配。呀!这个规则表达式将和刚刚附加到模式空间的三行的全部内容匹配。但我们要重新格式化该区域,而不是整个替换他。美元金额、支票号(假如有的话)和描述需要出现在替换字符串中。要这样做,我们用带有反斜杠的圆括号括起那些“感兴趣部分”,以便能够在替换字符串中引用他们(使用 '1'、'2 和 '3' 来告诉 sed 将他们插入到何处)。以下是最后的命令:

 s/nT(.*)nN(.*)nP(.*)/NUM2NUMttYtt3tAMT1AMT/  

该命令将我们的行变换成:

  28 Aug 2000  OUTY  INNY  NUMNUM    Y	   CHECKCARD SUPERMARKET	 AMT-8.15AMT 

虽然该行正变得好一些,但是,有几件事一看就有点...啊...有趣。首先是那个愚蠢的 "NUMNUM" 字符串 -- 其目的何在?假如查看 sed 脚本的后两行,就会发现其目的,后两行将把 "NUMNUM" 替换成 "-",而把 "NUM"<number>"NUM" 替换成 <number>。如您所见,用愚蠢的标记括起支票号允许我们在该字段为空时方便地插入一个 "-"。

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

最终的“QIF 到文本”脚本
 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/
/AMT-[0-9]*.[0-9]*AMT/b fixnegs
s/AMT(.*)AMT/1/ s/OUTY/-/ s/INNY/inco/
b done :fixnegs s/AMT-(.*)AMT/1/ s/OUTY/misc/
s/INNY/-/ :done }

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

         /AMT-[0-9]*.[0-9]*AMT/b fixnegs  

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

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

 28 Aug 2000	misc	-	-       Y     CHECKCARD SUPERMARKET  -8.15 

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

参考资料

  • 阅读 developerWorks 上 Daniel 的其他 sed 文章:通用线程:sed 实例,第 1 部分第 2 部分
  • 查看 Eric Pement 极佳的 sed faq
  • 能够在 ftp.gnu.org 找到 sed 3.02 资源。
  • 将在 alpha.gnu.org 找到很好的新的 sed 3.02.80。
  • 另外,Eric Pement 更有一些方便的 sed 单行程式,任何有抱负的 sed 高手都应该看一下。
  • 假如想看好的老式书籍,O'Reilly 的 sed & awk, 2nd Edition 将是极佳选择。
  • 可能想阅读 7th edition UNIX's sed man page(大概 1978!)。
  • 阅读 Felix von Leitner 短小的 sed tutorial
  • using regular expressions 中复习,发现和修改这个免费 dW 独家教程文本中的模式。

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