寫的一個perl程式
功能:從話單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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何編寫一個Perl爬蟲程式爬蟲
- Perl讀寫檔案&字串操作字串
- Perl IO:隨機讀寫檔案隨機
- 使用Perl和WWW::Mechanize庫編寫
- mpvue寫一個CPASS小程式Vue
- 編寫第一個Qt程式QT
- Perl程式:殭屍程式和孤兒程式
- 用 PHP 寫一個"程式語言"PHP
- 七個不一樣的Python程式碼寫法,讓你寫出一手漂亮的程式碼Python
- 編寫一個使用wreq庫的爬蟲程式爬蟲
- 如何寫一個 GNU 風格的命令列程式命令列
- 寫一個簡單的程式碼生成器
- perl的logwrapperAPP
- 基於 Lua 寫一個爬蟲程式爬蟲
- 分享一個奇怪得程式碼寫法
- 編寫一個程式求輸入字串的長度字串
- 用Java編寫一個最簡單的桌面程式Java
- 200行程式碼寫一個簡易的dva行程
- perl
- 寫一個菜鳥裹裹小程式吧
- Python使用Socket寫一個簡單聊天程式Python
- 送你一份perl書單
- 我打算寫一個《程式設計師的成長課》程式設計師
- 使用 Vala 編寫一個簡單的文字識別程式
- mod_perl到底是個什麼
- 還記得這門古老的程式語言麼,送你一份perl書單!
- 如何編寫一個使用Objective-C的下載器程式Object
- 仿寫一個簡單的微信小程式(番茄鬧鐘)微信小程式
- 請用canvas寫一個關於520浪漫表白的程式碼Canvas
- 寫java程式碼的一些個人感受和總結Java
- 編寫一個簡易計時器程式(edu)
- 請用js編寫一個紅綠燈程式JS
- 像寫部落格一樣寫程式碼,laf導致一個部門被裁
- 手寫一個自己的PromisePromise
- vue寫的一個拖拽容器Vue
- PhpOffice 寫一個漂亮的表格PHP
- 兩個將來可能很厲害的perl 專案:perl雲端計算及跟google app engine的結合GoAPP
- 個人總結的一些寫JS程式碼的基本規範JS
- 分享一個 Go 寫的仿 V2EX 的 BBS 社群程式:CasnodeGoV2EX