用perl 提取时间信息并处理数据--实例。

perl 也是我的最爱。简洁的处理方式,简明的表达方法。随手拈来的书写方式。

代码实例包含了很多信息, 

perl 易写难读, 针对性极强,简洁干练。

附上一例做模板用。省却查找之苦。

应用环境: 从众多的log 中提取时间信息, 计算期间的关系并打印出来

#!/usr/bin/perl -w
########################################
# author: hjjdebug
# date: 2012
#
########################################
# 命令行参数个数,执行文件名称
if(@ARGV<1)
{
    print "Usage: $0 <filename> \n";
    exit 1;
}
# 打开一个文件
open(FDR, "<", $ARGV[0]) || die $!;
# 全局变量设置
$timeSwitchChannel = 0;
$timeSetCW = 0;
$lastTime = 0;
# 读取文件内容
while(<FDR>)
{
    #匹配字符串
    if(/Ca_SetDescrambling begin/)
    {
        #打印当前行内容
        print $_;
        #匹配正则表达式
        if(/\d\d:\d\d:\d\d\.\d\d\d/)
        {
            #用定义函数提取时间信息
            $timeSwitchChannel = &time($&);
            $lastTime = $timeSwitchChannel;
        }

    }

    if(/CDSTBCA_ScrSetCW/)
    {
        print ;
        if(/\d\d:\d\d:\d\d\.\d\d\d/)
        {
            $timeSetCW_Bak = $timeSetCW;
            $timeSetCW = &time($&);
            if($lastTime == $timeSwitchChannel && $lastTime != $timeSetCW_Bak)
            {        
                $delta = $timeSetCW-$lastTime;
                if($delta < 3.0)
                {
                    #计算,格式化输出信息
                    printf("*** switch channel interval %.3f ***\n",$timeSetCW-$lastTime);
                }
                else
                {
                    printf("Warning!!!!!!  *** switch channel interval %.3f ***\n",$timeSetCW-$lastTime);
                }
            }
            else
            {
                $delta = $timeSetCW-$lastTime;
                if($delta < 18)
                {
                    #计算,格式化输出信息
                    printf("=== decode CW interval %.3f ===\n",$timeSetCW-$lastTime);
                }
                else
                {
                    printf("Warning!!!!!! === decode CW interval %.3f ===\n",$timeSetCW-$lastTime);
                }
            }
            $lastTime = $timeSetCW;
        }
        if(/(([\da-fA-F]{2}\s+){8})/)    # 多次匹配一个字符串, 例如:CDSTBCA_ScrSetCW begin >>> EcmPid:6678, pbyOddKey: EA 15 60 5F 88 64 EF DB
        {
            local $count = @{[$& =~ m/00/g]}; #匹配一个字符串的个数, 创建无名数组,取到数组个数 例如: pbyOddKey: EA 15 60 5F 88 00 00 00 
            if($count > 2)
            {
                print("Warning!!!!!! cw 0 count greater than 2, $&\n") ;
            }
            else
            {
                local $res = &JudgeCW($&);
                print ("Warning!!!!!! cw not valid, $&\n") if($res == 0);
            }

        }

    }

}

# 自定义函数,提取时间信息并给出整数值
sub time()
{
    my @array=split(/:/,$_[0]);
    my $value=$array[0]*3600+$array[1]*60+$array[2];
    return $value;
}

sub JudgeCW()
{
    local @data = split(/ /,$_[0]);
    local $sum1 = hex($data[0])+hex($data[1])+hex($data[2]);
    local $sum2 = hex($data[4])+hex($data[5])+hex($data[6]);
    if( 
        ($sum1 & 0xff) == hex($data[3]) &&
        ( $sum2 & 0xff) == hex($data[7])
    )
    {
        return 1;
    }
    else
    {
        return 0;
    }

}




分析:提取时间函数:

寥寥3行,就把时间提取出来了。

时分秒,一条语句就存储数据到一个数组里。 数组的表示是用@array

时分秒的用法。 用户不用关心数据类型, 整形,浮点型混合使用,返回的数据,会根据上下文,转化为你需要的类型。

函数的调用也很简单。 &time($&). $& 是什么? 是你匹配到的数据。

抽取,汇报的主要特点已经体现。

给一个代码分析数据的实例:

数据行:

01-19 15:39:33.814 V/stbca   ( 1568): ****** CDSTBCA_ScrSetCW begin >>> EcmPid:6438, pbyOddKey: C1 04 8F 54 9A B0 3C 86 , 

提取的时分秒

15:39:33.814

计算的时间值:

$value = 15*3600 + 39*60 + 33.814 = 3242373.814

2. 判断cw 是否合法函数:

a. 首先提取数据。用到了多次匹配字符串技术。

b. 得到一行匹配的次数简单写法。

c. 自定义校验和判断方法。

附录:perl 匹配
1.绑定操作符 =~ , !~, 绑定操作符的优先级非常高
2.  $` , $& , $’ 分别存有匹配内容左,匹配内容,匹配内容右的内容
3. 可以用()捕获特定的模式 并依次存入 $1 $2 $3 中
4. /i(忽略大小写) /g(全局) /m(多行,允许有换行符)
5. 量词:
    5.1.最大量词
    *  匹配0 或更多次
    + 匹配1 或更多次
    ? 匹配 1 或 0 次
    count}匹配count次
    {min,} 匹配至少min次
    {min,max} 匹配至少 min次,但不超过max次

    5.2.最小量词 (添加?)
    *? 匹配0次或更多次
    +?匹配1次或更多次
    ??匹配0次或1次
    {,min}? 匹配最多min次
    {min,max}? 匹配至少min次,但不超过max次
6. 常用的字母,数字正则元符号。
\d  数字 [0-9]
\D  非数字
\s  空格
\S  非空格
\w  匹配单词字符 [a-zA-Z0-9_], 就是微软的文件名称限制字符。
\W  非单词字符
\b  单词边界
\l  把下一个字符变成小写
\u  大写
----------------------------------------
()     模式内存
+ * ? {}     出现次数
^ $ \b \B     锚
|     选项
----------------------------------------
7.举例:
匹配十进制数字: ^-?\d+$
    行首,行尾,可有可无的符号,一系列数字.
匹配十六进制数字:^-?0[xX][\dA-Fa-F]+$
    行首,行尾,可有可无的符号,0x或0X 开始, 一系列数字或a-f A-F之间的字母


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值