烽火雷电
作者烽火雷电·2009-05-11 21:12
工程师·IBM

Perl 编程笔记

字数 7958阅读 1045评论 1赞 0

最近在为公司写个程序,这是我写的第一个程序,共耗时1周左右,不过今天终于完成了,而且还编译成了exe文件,写点感受,记录下;

程序的功能
1. 读取windows的log
2. 可支持参数
3. 可存成excel文件
4. 可以对相同的条目做归并处理
5. 需要能脱离系统运行
6. 可指定要读取的日志类型

先推荐几个网站
http://www.roth.net/perl/scripts/db/code/EVENTLOG.PL
http://www.cbi.pku.edu.cn/chinese/documents/perl/index.htm
http://www.perl.org/books/beginning-perl/

功能确定了,通过在网上搜索,确定使用perl语言实现这个功能,perl语言有以下好处:
1. 语法比较简单;
2. 可支持跨平台;
3. 比批处理复杂,但比C等简单

编程的一些知识点

如果你需要调用系统的库,你可以在脚本前面加上引用,想下面的例子
use Getopt::Long;

变量
$VERSION                       定义version变量;
%Config = (
    log     =>  'System',
    machine =>  '127.0.0.1',
    utput => 'c:\127.0.0.1.csv',
);                                        定义数组
@array = (1, 2, 3, 4);     定义数组
$scalar = $array[0];      数组拷贝
@array                             数组当前的长度,可用于循环;

循环和判断    和其他语言差不多

模式匹配,我觉得这个是他的特点,可以很方便的处理

$msg =~ s/"/'/g;  将msg变量中的“替换为‘
http://www.cbi.pku.edu.cn/chinese/documents/perl/perl6.htm

文件处理
如果要读写文件,首先要打开文件,基本的处理方法如下
1. open(FILE1,"file1");        // 打开文件
2. $line = <MYFILE>;从文件中读取一行数据存储到简单变量$line中并把文件指针向后移动一行 
3. @array = <MYFILE>;把文件的全部内容读入数组@array,文件的每一行(含回车符)为@array的一个元素。
4.   print OUTFILE ("Here is an output line.n"); 写文件
5. close (FILE1);  关闭文件
6. 文件测试
文件测试操作符
  语法为:-op expr,如:
    if (-e "/path/file1") {
    print STDERR ("File file1 exists.n");
    }

命令行参数

    $var = $ARGV[0]; # 第一个参数
    $numargs = @ARGV; # 参数的个数

关联数组
http://www.cbi.pku.edu.cn/chinese/documents/perl/perl9.htm
 1. 创建
%fruit = ("apples",17,"bananas",9,"oranges","none");
    此语句创建的关联数组含有下面三个元素:
  • 下标为apples的元素,值为17
  • 下标为bananas的元素,值为9
  • 下标为oranges的元素,值为none

  • 优点,可以知道每一个元素的意义,同时如果想找某个固定含义的值,无需遍历整个数组;
    2.  增删
     delete ($fruit{"lime"});
    注意:
    1、一定要使用delete函数来删除关联数组的元素,这是唯一的方法。
    2、一定不要对关联数组使用内嵌函数push、pop、shift及splice,因为其元素位置是随机的。

    调用windows 底层库函数
    $evt = Win32::EventLog->new( $syslog, "\\$Config{machine}")
    evt是句柄,可通过这个句柄调用库的函数
    $evt->GetNumber($total) || die "Can't get number of EventLog records: $!n";
    $evt->GetOldest($oldest) || die "Can't get number of oldest EventLog record: $!n";

    一个增加参数的例程
    sub Configure
    {
        my( $Config ) = @_;

        Getopt::Long::Configure( "prefix_pattern=(-|/)" );
        $Result = GetOptions( $Config,
                                qw(
                                    machine|m=s
                                    log|l=s
                                    output|o=s
                                    input|i=s
                                    date=s
                                    help|?
                                )
                            );
        $Config->{help} = 1 if( ! $Result );
        push( @{$Config->{machine}}, Win32::NodeName() ) unless( scalar @{$Config->{machine}} );
    }
    直接调用configure,就可以判断你是否有需要的参数;

    一个输出帮助的例程
    sub Syntax
    {
        my( $Script. ) = ( $0 =~ /([^\]*?)$/ );
        my $Whitespace = " " x length( $Script. );
        print<< "EOT";

    Syntax:
        $Script. [-m Machine] [-t EventType] [-l Log]
        $Whitespace [-h Hours] [-d Days] [-date Date]
        $Whitespace [-help]
            -m Machine......Name of machine whose Event Log is to be examined.
                            This switch can be specified multiple times.
            -l Log..........Name of Event Log to examine. Common examples:
                                Application
                                Security
                                System
                    -o Output file..Name of output file, default name is c:127.0.0.1.csv
                    -i Input File...Name of input file, if using this option, the -M and -l options is ignored.
            -date Date......Will consider events between specified date and before one month the specified
                            date .  Date is in international time format
                            (eg. 2000.07.18)                       
    EOT
    }
    编译:你可以把自己做好的pl程序编译成.exe可执行程序,这样就没有环境限制可直接运行。一个缺点是编译后文件较大,我的程序大约200行,编译完成后1.99M

    在安装http://aspn.ActiveState.com/ASPN/Mail/Browse/Threaded/ActivePerl. 程序后 ,你需要执行以下步骤;
    安装PAR比较麻烦,这里是如何安装,以及如何解决碰到的问题:

    第一步:ppm install par
    这个比较简单,当然如果幸运的话,你应该可以直接使用par了,但是我没有那么幸运,因为安装之后找不到pp.bat,实际上这是ActivePerl的问题,没办法只能往下继续了。

    第二步:重新安装par-packer
    不过之前要更新一个模块File-Temp,我原来的版本是0.12,太低,换成0.18的
    ppm install http://www.bribes.org/perl/ppm/File-Temp.ppd
    然后安装par-packer 0.975
    ppm install http://www.bribes.org/perl/ppm/PAR-Packer.ppd

    第三步:这时已经可以使用pp.bat了,但是你会发现pp不能生成exe文件,总是报
    erl lib version (v5.8.8) doesn't match executable version (v5.8.6)的错误,
    原因在于二进制不兼容,需要继续修改。
    第四步: 下载如下包

    http://backpan.perl.org/authors/id/S/SM/SMUELLER/PAR-Packer-0.976-MSWin32-x86-multi-thread-5.8.8.par

    第五步
    在dos窗口输入如下命令
    perl -MPAR::Dist -e”install_par( ‘PAR-Packer-0.976-MSWin32-x86-multi-thread-5.8.8.par’ )”
    系统可能会让你选择ppm程序打开;


    第六步:执行pp -o t.exe t.pl,不会报错,但运行时报错;

    Unrecognized character xEF at E:filename.exe line 1.

    第七步: 用UE打开你的程序,然后另存为无bom格式的pl文件,重新编译即可;








    如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

    0

    添加新评论1 条评论

    tonychencanadatonychencanada软件开发工程师shenzhen kimocomputer CO.,LTD
    2017-10-27 02:58
    thanks
    Ctrl+Enter 发表

    作者其他文章

  • sudo
    评论 0 · 赞 0
  • 一天一命令-software install
    评论 0 · 赞 0
  • HC 命令合集
    评论 0 · 赞 0
  • 【一天一命令】-20090330
    评论 1 · 赞 0
  • X社区推广