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"。现在,让我们看一下最终脚本:
1d /^^/d s/[[:cntrl:]]//g /^D/ { s/^D(.*)/1tOUTYtINNYt/ |
附加的十一行使用替代和一些分支功能来美化输出。首先看一下这行:
/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
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!




