鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 服务器相关 > 批处理 > >

[简洁Perl指南II]PERL程序的示例与浅析

来源:互联网 作者:佚名 时间:2015-09-27 08:33
本文展示一个自己写的小 程序 ,给初学者看看简单的Perl 程序 是什么样子的。读者可以借此粗略了解Perl的语法要点。 #---------------------------- #!/usr/bin/perl -w #此句用于在Linux系统指出Perl 程序 的路径,在Wind系统中可以省略 use Net::FTP; #Per

     本文展示一个自己写的小程序,给初学者看看简单的Perl程序是什么样子的。读者可以借此粗略了解Perl的语法要点。

#----------------------------

#!/usr/bin/perl -w #此句用于在Linux系统指出Perl程序的路径,在Wind系统中可以省略
use Net::FTP;     #Perl自带的FTP函数包,实现FTP文件传输功能。 use表示包含某个函数包
use DBI;     #Perl的Database Interface函数包
use DBD::mysql;    
 #Perl的MYSQL数据库函数包,使用MYSQL必须安装
#use strict;    
 #use strict 表示Perl解释器强制要求变量在使用前定义

@DbSerial= qw(CallProcessing DDFData DynamicDB EmsData MMAppConfigData 
        sS7Configuration SubscriberData SystemConfiguration WirelessData); 
#定义一个字符串组成的数组。   qw算是一个函数

my $RootPath = "D:/Alcatel/";    #定义一个字符串变量
my $ElementID = "SHG62";
# 获得系统时间
my @TimeArray=(localtime)[5,4,3,2,1,0,6]; # s,m,h,d,m,y,星期   #定义一个数组,其元素依次是localtime的元素:秒,分,时,天,月,年,星期
$TimeArray[0]+=1900;   #[X]表示数组的下标
$TimeArray[1]+=1;
my $CurrentDate=sprintf("%04u%02u%02u",$TimeArray[0],$TimeArray[1],$TimeArray[2]);   
#sprintf的用法类似C,构造字符串

# 建立本地文件目录
my $LocalBulkPath = $RootPath.$CurrentDate; # "."可以直接连接两个字符串
mkdir($LocalBulkPath);    #DOS命令:make dir
# 设置远程目录
my $RemoteBulkPath;
if ($TimeArray[6]== 0) #判断语句的语法同C
{$RemoteBulkPath='/space/dbbackup/Weekly/'.$CurrentDate.'034501/bulk';}   #"\"作为转义字符,所以Perl中表示文件路径尽量全用"/"
else
{$RemoteBulkPath='/space/dbbackup/Daily/'.$CurrentDate.'034501/bulk';}

## 登录FTP
my $FtpHost="10.221.1.197";
my $ftp=Net::FTP->new($FtpHost) or die "cannot connect to ftp server $!\n";   #Net::FTP的函数,新建一个FTP对象。 dir:输出错误信息并退出程序
$ftp->login("root","solaris8"); #这儿的**是我的密码   #函数包的函数用法尽可参考手册或查看其源代码
mkdir($LocalBulkPath.'/CallProcessing');
$ftp_file_path = $RemoteBulkPath.'/CallProcessing';
#$local_file_path = $LocalBulkPath.'/CallProcessing';

$ftp->cwd($ftp_file_path)or print "get faild",$ftp->message;;
$ftp->get() or print "get faild",$ftp->message;
$ftp->quit;

mkdir($LocalBulkPath.'/CallProcessing');
mkdir($LocalBulkPath.'/DDFData');
mkdir($LocalBulkPath.'/DynamicDB');
mkdir($LocalBulkPath.'/EmsData');
mkdir($LocalBulkPath.'/MMAppConfigData');
mkdir($LocalBulkPath.'/SS7Configuration');
mkdir($LocalBulkPath.'/SubscriberData');
mkdir($LocalBulkPath.'/SystemConfiguration');
mkdir($LocalBulkPath.'/WirelessData');


$ScriptFile = $LocalBulkPath."/bat".$CurrentDate.".bat";
open (MYFILE,">$ScriptFile") or die "Fail to open $!\n";   #打开或新建一个文件对象用于写入,文件句柄MYFILE
print MYFILE "open 10.221.1.197\n"; #MYFILE所指向的文件写入内容。此程序是把dos命令写在一个BAT批处理文件中,然后调用改批命令下载文件。
print MYFILE "root\n";
print MYFILE "solaris8\n";
print MYFILE "cd $RemoteBulkPath\n";
print MYFILE "cd CallProcessing\n";
print MYFILE "lcd $LocalBulkPath/CallProcessing\n";

...省略相似代码若干行...

print MYFILE "Disconnect\n";
print MYFILE "bye\n";
close(MYFILE);   #关闭文件流对象
system("ftp -i -s:".$ScriptFile); #system:调用dos命令ftp
#下载完毕

#入库
#先建立数据库

open (WF,">C:/temp.txt"); 
foreach $DbSerial (@DbSerial)    #遍历数组的foreach循环。注意:$DbSerial和@DbSerial是不同的变量
{
$Dirname = "$LocalBulkPath/$DbSerial";
my @FileList = <$Dirname/*>;
foreach $FileList (@FileList) 
{
   print WF "$FileList\n";
   &CreateDB($FileList); #调用子函数,前面的&是什么含义。。。我忘记了
}


}
close(WF);
print "finish";


sub CreateDB() #定义一个子函数
{
$FileName = $_[0]; #在函数定义中 $_[]是一个表示输入参数的数组,$_[0]表示第一个参数,以此类推。注意:$_[]和$_是不同的变量
# 连接数据库
my ($dbh, $sth, $count);
$dbh = DBI->connect ("DBI:mysql:host=10.9.56.177;database=SSAC", 
                    "root", "123",{PrintError => 0, RaiseError => 1});   #DBD::MYSQL中连接数据库的代码
# 数据表名字
$_ = $FileName;
m/(\w+)_\w+.(\w+).bulk/;   #字符串模式识别,$FileName是形
如"callprocessing_spatial.AMACNARECORDING.bulk"的形式,则$1=callprocessing,$2=AMACNARECORDING
$TableName = $1."_".$2;

print("$TableName\n"); 
$sth = $dbh->prepare ("CREATE TABLE $TableName(NE VARCHAR(10),DATADATE DATE);");$sth->execute (); #prepare()和execute()合在一起执行依据SQL语句
                    
open (MYFILE,$FileName) or die "cannot connect to ftp server $!\n";
my @DomainList;
my @TypeList;
$idx = 0;
while(<MYFILE>) #<>表示读取该文件中的一行,并自动指向下一行
{
   if(m@^# +\d@)   
 #此处的m@@很碍眼,实际上,PERL并没有对把模式识别括起来的分隔符作出规定。该处匹配形以"# "和一串数字开头的字符串

   {
    m/\d. ([\w\d]+) +([\w\d\(\)]+)/;#模式识别,这句话是对默认变量$_进行识别。该处输入形如"#      2. AMACNARECORDINGCOND1 INTEGER",则$1=AMACNARECORDINGCOND1 ,$2=INTEGER。
    $DomainList[$idx] = $1;
    $_ = $2;
    if (m/CHAR\((\d+)\)/) #匹配包含 CHAR和一串数字的行
    {
     print("$_\t"); 
     $CharLen = $1;
     if ($CharLen>255)
     {
     s/$CharLen/255/; #s/a/z/表示查找字符串a并替换成z。如此处,查找$CharLen变量的值,并替换成255
    
    } 
    print("$_\n");
    }
    s/VARBINARY\(.*\)/VARCHAR(20)/; #查找"VARBINARY"及其后任意字符,替换成"VARCHAR(20)/"
    s/BINARY\(.*\)/VARCHAR(20)/; #查找"BINARY"及其后任意字符,替换成"VARCHAR(20)/"
    $TypeList[$idx] = $_;

    $sth = $dbh->prepare ("ALTER TABLE $TableName ADD COLUMN _$DomainList[$idx] $TypeList[$idx];");$sth->execute ();
    $idx += 1;
   }
  
}
$sth->finish (); #关闭数据库连接对象和数据库连接
$dbh->disconnect ();
close(MYFILE);
}


网友评论
<