博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助

PowerShell

努力做中文最好的Windows PowerShell学习基地 本Blog所发表的所有"原创文章", 除特别说明, 均可转载, 转载请保留作者姓名, 链接. 谢谢
   PowerShell.cublog.cn
关于作者  
联系邮箱:
PowerShellCn<AT>hotmail{DOT}com
PowerShellCn<AT>gmail{DOT}com
PowerShell<AT>163{DOT}com

我的分类  




[原创]PowerShell处理文本文件

今天, 我们讨论一个使用正则表达式的问题. 题目源于某论坛, 内容如下:

-----------------------需求-------------------------
原始文件:(编号,姓名,工资)
-------------------------------------------

00014367423811520328285王小勇-109.00
C0024367423811520214121刁晓用-7.25
00034367423811520214071喻大森409.00
10014367423811520212695吕二青234.18
10036227003818620017835王得丹679.49
D0046227003813550029454刘小波767.22
R0054367423811520212943徐小明559.32

希望得到:

1︱4367423811520328285︱王小勇 | 0
2︱4367423811520214121︱刁晓用︱0
3︱4367423811520214071︱喻大森︱409
4︱4367423811520212695︱吕二青︱234.18
5︱6227003818620017835︱王得丹︱679.49
6︱6227003813550029454︱刘小波︱767.22
7︱4367423811520212943︱徐小明︱559.32
合计                   | 2649.21
   
-----------------------------------------------
1) 加入序号
2)用 | 分割各项
3)去掉编号前4个字符
3) 工资项若为负数,变为 0
4)最后将工资为正的,统计相加
 
-----------------------分析-------------------------
 
这种题目显然使用正则表达式是最方便不过的. 首先将源文件保存为salary.txt.
我把这个文件保存在 C:\Documents and Settings\Administrator 目录下, 请大家注意, 尽量避免使用管理员权限.
 
我们要从原始数据中提取出3个信息: 编号, 姓名, 工资项.
它们都有各自固定的特点, 因此我使用下面的正则表达式分别匹配这三项:
^.{4}(?<id>\d+)
(?<name>[\p{IsCJKUnifiedIdeographs}]+)
(?<salary>[\d.]*)
 
匹配名称时候, 我指定了中文, 日文, 韩文的特定集合. \p{IsCJKUnifiedldeographs}. 我想这是整个正则表达式的关键部分.
(?<>re)中, 指定正则表达式分组, <>中间是分组的名称. re是正则表达式.
 
现在, 我给出最后的代码样子:
 
${C:salary.txt} | `
ForEach-Object { $total = 0; $id = 1 } `
{ [void] ($_ -match '^.{4}(?<id>\d+)(?<name>[\p{IsCJKUnifiedIdeographs}]+)(?<salary>[\d.]*)'); `
$ofs = '|'; `
"$($id;$id++;$matches.id;$matches.name;'{0:F2}' -f [float]$matches.salary)"; `
$total += $matches.salary } `
{ "合计`t`t|$total" }
 
第一行从C:当前工作目录读取文件salary.txt, 然后通过管道, 传递给ForEach-Object命令. 首先我初始化了两个变量$total和$id, 分别用于记录最终的汇总值和每条记录的id号.
接下来正则表达式从输入中将信息分别匹配出来. 这些匹配的分组被保存在$matches哈希表中.
设置输出分隔符为|
拼接输出的信息: id, 员工id, 姓名, 然后用-f运算符指定浮点数的格式.
并将每个salary加到$total中.
最后打印汇总信息.
 
这里我利用了一个小技巧, 因为题目要求负数等价于0, 因此正则表达式就没有考虑负数的情况. $matches.salary就是$null值. $null值可以在数学运算中转化为数值0, 因此方便了整个脚本的实现.

 TAG PowerShell 正则表达式 文本文件处理
 发表于: 2008-06-10,修改于: 2008-06-10 21:51 已浏览573次,有评论1条 推荐 投诉

  网友评论
  本站网友 时间:2008-07-08 22:43:25 IP地址:158.132.12.★
同样的功能用Perl就是
while (<>) {
    s/[\n\r]+//g;
    if (/.{4,4}(\d+)([^\-\d]+)([\-\.\d]+)/) {
        $fv=$3<0?0:$3;
        $total += $fv; $i++;
        print "$i|$1|$2|$fv\n";        
    }
}

print "Total:\t\t$total\n";
暂时没有看出来, Power Shell 强在哪里

Blog作者的回复:
既然不知道, 那么花点时间学习下吧. 任何没有接触的事物, 你都不可能在没有任何调查之前, 下过多的定论. PowerGUI 中扩展的特性很强大, 如果有兴趣, 你可以了解下, 就能体会PowerShell的优势了. 

不知道perl目前是否支持xaml制作GUI的程序的程序? 暂时可能不行吧. 

我觉得Perl是很好的语言, PowerShell也从中借鉴了一些东西. 


  发表评论



Copyright © 2001-2006 ChinaUnix.net All Rights Reserved

感谢所有关心和支持过ChinaUnix的朋友们
页面生成时间:0.67392

京ICP证041476号