寫的一個perl程式

wangzh3發表於2005-08-10

功能:從話單ftp伺服器獲取話單,然後備份到備份ftp伺服器,然後對話單做處理,然後入庫。

用到了其他幾個perl模組,可以到cpan.org上去下載,安裝就ok了(linux/unix下需要使用root使用者安裝),其他的看說明。

[@more@]

cdr2db.pl

#!/usr/bin/perl
#CopyRight @2005
#writer :
#revsion : 2005-07-29 08:50 增加對要訪問資料庫tns的配置
# 2005-07-29 08:55 增加在資料庫無法訪問的時候不刪除檔案的處理
# 2005-07-29 09:15 增加對備份ftp伺服器上目錄不存在時的異常處理
# 2005-07-29 09:19 增加對備份ftp伺服器上不可用時對話單的本地備份處理
# 2005-07-29 09:38 增加對備份ftp伺服器上目錄不可用,建立仍不可用的處理
# 2005-07-30 09:38 增加對獲取檔案的名字的限定,只獲取RING開頭的檔案
# 2005-07-30 09:43 合併配置檔案
# 2005-07-30 09:56 對獲取過來檔案轉換後名字加字首"sqlldr.",只備份原始話單檔案,如果該檔案無法入庫,則一直放在該目錄下等待人工處理
# 2005-07-30 10:36 增加對配置檔案的冗餘,廣東需要配置兩個備份路徑,其他地方可能一個
# 2005-07-30 11:33 增加對本地路徑是否存在的判斷,如果不存在,建立

use strict;
use warnings;
use File::Copy;
use File::stat;
use File::Find;
use Net::FTP;
use Net::FTP::File;
use Date::Parse;
use Oracle::SQLLoader qw/$CHAR $INT $DECIMAL $DATE/;
use Time::Local;
use FileHandle;
use File::chdir;
use Cwd;
use Config::IniFiles;
##================================================================##
#獲取當前年月日YYYY-MM-DD HH:MI:ss格式
sub timeString {
my $year = (localtime())[5];
my $mon = (localtime())[4];
my $mday = (localtime())[3];
my $hour = (localtime())[2];
my $min = (localtime())[1];
my $sec = (localtime())[0];

return sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year+1900, $mon+1, $mday, $hour, $min, $sec);
}

sub yyyymmddString {
my $year = (localtime())[5];
my $mon = (localtime())[4];
my $mday = (localtime())[3];
return sprintf("%04d%02d%02d", $year+1900, $mon+1, $mday);
}
##================================================================##


##================================================================##
#判斷程式引數個數
if((my ){
print "***********************************************n";
print "** usuage: cdr2db.pl path **n";
print "** usuage: path 為該perl程式的安裝路徑 **n";
print "** writer: wangzhihong.china@gmail祝你一切順利**n";
print "***********************************************n";
exit;
}else{
print "***********************************************n";
print "** CopyRight:@2005 **n";
print "** **n";
print "** writer: wangzhihong.china@gmail祝你一切順利**n";
print "***********************************************n";
}
##================================================================##

##================================================================##
#獲取配置資訊
##獲取配置檔案所在路徑
my $config_path=shift(@ARGV);
#讀取配置檔案。
my $cdr2db_cfg = Config::IniFiles->new( -file => "$config_path/cdr2db.config" );
## FTP伺服器的IP地址 ##
my $ftp_server = $cdr2db_cfg->val('FTPServer', 'ftp_server') ||'';
## 指定的FTP上傳目錄路徑 ##
my $ftp_dir = $cdr2db_cfg->val('FTPServer', 'ftp_dir') || '';
## FTP的登陸使用者名稱 ##
my $ftp_userid = $cdr2db_cfg->val('FTPServer', 'ftp_userid') || '';
## FTP的登陸密碼 ##
my $ftp_passwd = $cdr2db_cfg->val('FTPServer', 'ftp_passwd') || '';
##備份ftp伺服器地址
my $put_server = $cdr2db_cfg->val('FTPServer', 'put_server') || '';
##備份路徑1
my $put_dir1 = $cdr2db_cfg->val('FTPServer', 'put_dir1') || '';
##備份路徑2
my $put_dir2 = $cdr2db_cfg->val('FTPServer', 'put_dir2') || '';
##備份ftp伺服器使用者名稱
my $put_userid = $cdr2db_cfg->val('FTPServer', 'put_userid') || '';
##備份ftp伺服器密碼
my $put_passwd = $cdr2db_cfg->val('FTPServer', 'put_passwd') || '';
##獲取的話單檔案放置在本地的臨時路徑
my $local_path = $cdr2db_cfg->val('FTPServer', 'local_path') || '';
##如果備份ftp伺服器不可用,暫時放到本地
my $local_bak_path =$cdr2db_cfg->val('FTPServer', 'local_bak_path') || '';
##================================================================##


##================================================================##
##如果本地目錄和本地備份目錄不存在,建立之
if (! -e $local_path){
mkdir($local_path)||die("cannot make dir $local_path");
}

if (! -e $local_bak_path){
mkdir($local_bak_path)||die("cannot make dir $local_bak_path");
}
##================================================================##


##================================================================##
#讀取資料庫部分的配置資訊
##oracle_home
my $ORACLE_HOME=$cdr2db_cfg->val('DB', 'ORACLE_HOME') || '';
my $ORACLE_SID=$cdr2db_cfg->val('DB', 'ORACLE_SID') || '';
my $db_userid = $cdr2db_cfg->val('DB', 'db_userid') || '';
my $db_passwd = $cdr2db_cfg->val('DB', 'db_passwd') || '';
##要sqlldr的目標表的名字
my $table_name = $cdr2db_cfg->val('DB', 'table_name') || '';
##目標表的欄位列表,要和檔案中的欄位順序一致。
my $column_name =$cdr2db_cfg->val('DB', 'column_name') || '';
##================================================================##

##================================================================##
##設定環境變數
if($ENV{'ORACLE_HOME'} eq ''){
$ENV{'ORACLE_HOME'} = "$ORACLE_HOME";
}

if($ENV{'ORACLE_SID'} eq ''){
$ENV{'ORACLE_SID'} = "$ORACLE_SID";
}
##================================================================##

##================================================================##
## 記錄全部過程的日誌檔案準備,每天生成一個日誌檔案
my $yyyymmdd = yyyymmddString();
my $logfilename = "cdr2db$yyyymmdd.log";

#進入對應目錄
$CWD = "$local_path";

my $HLOG = new FileHandle;
$HLOG->open(">>$logfilename") or die("開啟日誌檔案出錯:檔名為 $logfilename ;錯誤原因為: $!");

my $g_strLastError;
##================================================================##

##================================================================##

LOG("自動ftp獲取話單檔案、入庫並備份到話單伺服器 Version 1.2");
LOG("Copyright @2005 ");
##================================================================##

##================================================================##
#ftp
LOG("正在連結至指定FTP伺服器($ftp_server)...");
my $ftp = Net::FTP->new($ftp_server);
if($@)
{
$g_strLastError = "不能連線到FTP伺服器($ftp_server),錯誤原因:".$@;
LOG("$g_strLastError@");
}
else
{
$ftp->login($ftp_userid, $ftp_passwd);
if($@)
{
$g_strLastError = "不能登陸FTP伺服器($ftp_server),錯誤原因:".$@;
LOG("$g_strLastError");
}
else
{
$ftp->binary;
LOG("連結FTP伺服器成功!");
LOG("開始獲取話單檔案");
##================================================================##

##================================================================##
#獲取ftp伺服器上crcdr目錄下的路徑或者檔名稱
$ftp->cwd($ftp_dir);
my @files = $ftp->dir($ftp_dir);

my($access,$link,$user,$group,$size,$month,$day,$ctime,$filename);

for my $file(@files){

($access,$link,$user,$group,$size,$month,$day,$ctime,$filename)=split(/s+/,$file);

if ((defined $filename)&&($filename !~/./)&&($filename !~/bak/)){
LOG("********enter $ftp_dir/$filename/cdr*********");
$ftp->cwd("$ftp_dir/$filename/cdr");

my @cdrfiles=$ftp->dir("$ftp_dir/$filename/cdr");

for my $cdrfile(@cdrfiles){

my($a,$l,$u,$g,$s,$m,$d,$t,$cdrfilename)=split(/s+/,$cdrfile);
#如果不是.w或者.W結尾的檔案則獲取,上述二者是正在上傳的檔案,RING開頭的檔案
if ($ftp->isfile($cdrfilename)&&($cdrfilename !~ /[w|W]/)&&($cdrfilename=~/^RING/)){
LOG("get cdr file :$cdrfilename");
$ftp->get($cdrfilename);
$ftp->delete($cdrfilename);
}
}
}
}

}
LOG("ftp話單檔案完畢");
$ftp->quit();
LOG("退出ftp");
}
##================================================================##

##================================================================##
#備份
$CWD = "$local_path";
my @putfiles=();
sub wanted_put{
if (-f $File::Find::name){
#包含RING,並且不是
if (($File::Find::name=~/RING/)&&($File::Find::name !~/sqlldr/)){
push @putfiles,$_;
}
}
}

find (&wanted_put,"$local_path");

LOG("正在連結至指定備份FTP伺服器($put_server)...");
my $put = Net::FTP->new($put_server);
if($@)
{
$g_strLastError = "不能連線到備份FTP伺服器($put_server),錯誤原因:".$@;
LOG("$g_strLastError@");
#把獲取的原始備份到本地
find(&wanted_bak,"$local_path");
LOG("備份話單到本地,從$local_path到$local_bak_path"); }
else
{
$put->login($put_userid, $put_passwd);
if($@)
{
$g_strLastError = "不能登陸備份FTP伺服器($put_server),錯誤原因:".$@;
LOG("$g_strLastError");
#把獲取的原始備份到本地
find(&wanted_bak,"$local_path");
LOG("備份話單到本地,從$local_path到$local_bak_path");
}
else
{
$put->binary;
#判斷對應備份目錄是否存在,不存在,建立

#判斷第一個備份目錄是否配置
if ($put_dir1 ne ''){
LOG("在備份ftp伺服器($put_server)上配置了備份目錄$put_dir1");
if(!$put->exists($put_dir1)){
LOG("在備份ftp伺服器($put_server)上$put_dir1不存在,建立");
if($put->mkdir($put_dir1)){
#建立成功
LOG("在備份ftp伺服器($put_server)上建立$put_dir1成功");
}else{
LOG("在備份ftp伺服器($put_server)上建立$put_dir1失敗");
};
}
}else{
LOG("在備份ftp伺服器($put_server)上沒有配置備份目錄put_dir1");
LOG("請配置至少一個備份目錄,否則將備份在本地!");

}

#判斷第二個備份目錄是否配置
if ($put_dir2 ne ''){
LOG("在備份ftp伺服器($put_server)上配置了備份目錄$put_dir2");
if(!$put->exists($put_dir2)){
LOG("在備份ftp伺服器($put_server)上$put_dir2不存在,建立");
if($put->mkdir($put_dir2)){
#建立成功
LOG("在備份ftp伺服器($put_server)上建立$put_dir2成功");
}else{
LOG("在備份ftp伺服器($put_server)上建立$put_dir2失敗");
};
}
}else{
LOG("在備份ftp伺服器($put_server)上沒有配置備份目錄put_dir2");
}


#再次判斷備份目錄是否存在,如果不存在,備份,不再ftp
if($put->exists($put_dir1) || $put->exists($put_dir2)){
LOG("登陸備份ftp伺服器($put_server),開始備份話單檔案");
for my $putfile(@putfiles){
$put->cwd($put_dir1);
LOG("backup cdr file: $putfile ");
$put->put($putfile);
if ($put_dir2 ne ''){
#如果第二個備份目錄不為空
$put->cwd($put_dir2);
$put->put($putfile);
}
}
LOG("把cdr話單備份到備份ftp伺服器完畢");
}else{
LOG("備份ftp伺服器($put_server)上$put_dir1和$put_dir2均不存在,且無法建立");
LOG("故,備份到本地$local_bak_path");
#把獲取的原始備份到本地
find(&wanted_bak,"$local_path");
LOG("備份話單到本地,從$local_path到$local_bak_path");

}
}
$put->quit();
LOG("退出備份ftp伺服器");

}

##================================================================##


##================================================================##
#處理話單檔案
#轉換後的話單檔名加字首"sqlldr."
$CWD = "$local_path";
LOG("開始轉換話單檔案");

foreach my $file(@putfiles){
my $suffix = substr($file,length($file)-3,length($file));
my $newfile ="sqlldr.$file";
open(FH,$file);
open(NewFH,">$newfile");
while(){
if (($_ !~/RING/)&&($_ !~/END/)){
$_=~s/s+/|/g;
$_.="$suffix";
print NewFH "$_n";
}
}
close(FH);
close(NewFH);
unlink($file);
}


LOG("處理話單檔案完畢");
##================================================================##

##================================================================##
#話單入庫
$CWD = "$local_path";

LOG("開始把話單檔案入庫");

my @columns=split /,/, $column_name;
LOG("配置的環境變數ORACLE_HOME:$ENV{'ORACLE_HOME'}");
LOG("目標資料庫的tnsname:$ENV{'ORACLE_SID'},");

foreach my $cdrfile(@putfiles){
my $indbfile="sqlldr.$cdrfile";
LOG("indb cdr file: $indbfile");
my $ldr = new Oracle::SQLLoader(
infile => "$local_path/$indbfile",
terminated_by => '|',
username => "$db_userid",
password => "$db_passwd",
)||die "$@";

$ldr->addTable(table_name => "$table_name");

foreach my $column(@columns){
$ldr->addColumn(column_name =>"$column");
}

if($ldr->executeLoader()){
unlink("$indbfile");
}
else{
LOG("indb cdr file fail:$indbfile".$@);
}

}

LOG("話單檔案入庫完畢");
LOG("本次任務結束,^_^!nnnn");
##================================================================##


##================================================================##
#關閉日誌檔案
$HLOG->close();

##================================================================##
#sub LOG

sub LOG {
my ($text) = @_;
my $time = timeString();

# log to stdout.
print "[$time] $textn";

# log to logfile.
print $HLOG "[$time] $textn";

}
##================================================================##

##================================================================##
#本地話單備份
sub wanted_bak{
if (-f $File::Find::name){
if ($File::Find::name=~/RING/){
my $cdr_file_name=$_;
copy($File::Find::name,"$local_bak_path/$cdr_file_name");
}
}
}
##================================================================##

cdr2db.config

[FTPServer]
#話單檔案存放的ftp伺服器ip
ftp_server=10.40.45.65
#ftp伺服器上話單檔案存放的根路徑,/crcdr/129/cdr
ftp_dir=/crcdr
#ftp使用者名稱
ftp_userid=zxin10
#ftp密碼
ftp_passwd=zxin10
#獲取到本地後放置的路徑
local_path=/home/zxin10/wangzh


#備份ftp伺服器ip
put_server=10.40.45.65
#備份路徑1
put_dir1=/tmp
#備份路徑2,可以為空,理論上來說至少需要備份在一個路徑,所以備份路徑1不能為空
put_dir2=
#備份ftp伺服器使用者名稱
put_userid=zxin10
#備份ftp伺服器密碼
put_passwd=zxin10
#如果無法備份到ftp伺服器,本地備份路徑,注意要和上面的local_path不能有包含關係
local_bak_path=/home/zxin10/fuck

[DB]
#ORACLE_HOME
ORACLE_HOME=/u01/product/oracle9i
#資料庫服務名tnsname
ORACLE_SID=zx10_40_95_158
#資料庫使用者名稱
db_userid=crgw_user
#資料庫密碼
db_passwd=crgw_user
#入庫的表名
table_name=s50stattemp
#表的欄位名
column_name=USERNUMBER,ISPAY,SETTYPE,OPERTYPE,RINGTYPE,RINGID,CDRTIME,RINGFEE,SPCODE,USERTYPE,RESDATA,AREACODE

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/47869/viewspace-804187/,如需轉載,請註明出處,否則將追究法律責任。

相關文章