2012-12-01 32 views
0

我的数据文件:由空格分隔的每个条目导入日志文件数据到应用程序

VOTE 1168241980 Campaign:ssss_uk_01B Validity:during 
Choice:Tupele CONN:MIG00VU MSISDN:00088866655598 
GUID:A34-FDS87-FHDHDH-DHDHDHD0 Shortcode:63334 

:votes.txt与行相同地形成。我目前有19行的样本。

领域:

CONN:MIG00VU MSISDN:00088866655598 
GUID:A34-FDS87-FHDHDH-DHDHDHD0 Shortcode:63334 

不被用于这项工作。

#!/usr/bin/perl 

use warnings; 
use strict; 
use Switch; 
use DBI(); 

# 
# _voting.pl 
# 

# Connect to the database. 
my $dbh = DBI->connect("DBI:mysql:database=sms_voting;host=localhost", 
        "sisisi", "*********", 
        {'RaiseError' => 1}); 

my $sth = $dbh->prepare("INSERT INTO voting 
(epoch, validity, choice, campaigns_id, candidates_id) VALUES (?,?,?,?,?)"); 

open (LOGFILE, '/var/www/voting/votes.txt') or die("Could not open log file."); 

my $errors = 0; 
my $campaign_id = 0; 
my $candidate_id = 0; 

foreach my $line (<LOGFILE>) { 

    my ($vote, $epoch, $campaign, $validity, 
$choice, $CONN, $MSISDN, $GUID, $Shortcode) = split(' ', $line); 

# parse the field:value entries... 
$campaign = substr $campaign, 8, 11, ''; 
$validity = substr $validity, 9, 6, ''; # during 
$choice = substr $choice, 7, 10, ''; # Brown 

# case statements to define correct foreign keys... 
switch ($campaign) { 
     case ("ssss_uk_01B") { $campaign_id = 1 } 
     case ("ssss_uk_01C") { $campaign_id = 2 } 
     case ("ssss_uk_01D") { $campaign_id = 3 } 
     case ("ssss_uk_01E") { $campaign_id = 4 } 
     case ("ssss_uk_01F") { $campaign_id = 5 } 
     case ("ssss_uk_01G") { $campaign_id = 6 } 
} 

switch ($choice) { 
     case ("Brown")  { $candidate_id = 1 } 
     case ("Cameron") { $candidate_id = 2 } 
     case ("Balls")  { $candidate_id = 3 } 
     case ("Green")  { $candidate_id = 4 } 
     case ("Boring")  { $candidate_id = 5 } 
     case ("Tupele")  { $candidate_id = 6 } 
} 

if ($epoch && $validity && $choice && $campaign_id && $candidate_id) { 

    $sth->execute($epoch, $validity, $choice, $campaign_id, $candidate_id); 
    # debug 
    print "$epoch $validity $choice \n"; # 1161048980 during Green 
    next; 
} 

$errors++; 
} 

close (LOGFILE); 

# debug 
print qq(errors=$errors\n); 

对foreach,在$活动和$选择变量的各回路通过switch语句,以便确定candidate_id & CAMPAIGN_ID号运行。这些外键将映射到候选人&广告系列表。

查看:http://acookson.org/wp-content/themes/cookie_23112012/img/sms_voting.png为数据库模型。

INSERT INTO voting (epoch, validity, choice, campaigns_id, candidates_id) 
VALUES (1161048980,'during','Brown', 1, 1), 
(1161048980,'during','Tupele', 3, 5), ... etc 

任何空在votes.txt检测值将导致$误差变量被递增。

该脚本似乎成功地通过votes.txt循环但未能初始化:$ campaign_id & $ candidate_id variables resp。完成后,错误= 19被打印到终端;我的示例数据votes.txt中的总行数;含义 此文件中的每一行未能插入到数据库中。

mysql> select * from voting; 
Empty set (0.00 sec) 

证实了这一点。

脚本报告没有语法错误;因此它更低一些。没有开关就能正常工作;因此这有所缩小。但我无法看到交换机的问题,所以我在这里寻找建议。

+0

据我所知,'Switch'模块在perl v5.10.1中已被弃用,并由'given/when'功能取代。参见[perldoc perlsyn](http://perldoc.perl.org/perlsyn.html#Switch-Statements)。但是,我会建议您使用散列来代替该查找。 – TLP

回答

0

不知道你的问题是什么,但是这里有一些关于你的Switch语句和其他代码的指针。

据我所知,use Switch功能/模块已在perl v5.10.1中被替换为given/when功能,现在已被弃用。就我个人而言,我一直认为这些陈述有点奇怪和不可靠。由于perl是一种非常灵活的语言,因此无论如何都无法替代。

在你的情况,我建议哈希查找来代替:

my %camp = ("ssss_uk_01B" => 1, 
      "ssss_uk_01C" => 2, 
      ...); 
my %cand = ("Brown"  => 1, 
      "Cameron"  => 2, 
      ...); 

$campaign_id = $camp{$campaign}; 
$candidate_id = $cand{$choice} 

如果您需要提供默认值,你可以使用defined-or赋值运算符:

$campaign_id //= "default value here"; 

substr分配是有点不对。首先,您使用的所有四个参数,这是的perldoc这样描述:

substr EXPR,OFFSET,LENGTH,REPLACEMENT 

这意味着你与''空字符串替换你的对手。这会影响变量本身,并会删除您想要的数据,如果自己留下的话。你的情况下的长度也是不需要的,因为它是你之后字符串的结尾。最后,通过使用substr声明的返回值,可以节省您的时间。

最后,当我试用您的作业时,我的第一个作业($campaign)出现一次性错误。输出是:ssss_uk_01,并且您期望ssss_uk_01

要正确使用substr功能,您应该使用:

$campaign = substr $campaign, 9; 
$validity = substr $validity, 9; 
$choice = substr $choice, 7; 
+0

非常丰富,谢谢。 – cookie

+0

不客气。 – TLP

0

我同意TLP的使用哈希值的查找表的建议。但是在实际的应用程序中,这些查找表应该填充数据库查找,以避免在其他表中的数据更改时需要更改应用程序。

我也倾向于不太相信日志中数据的格式。使用分割减轻了需要知道标签的确切长度+结肠大小。除此之外,我还建议在将数据用作查找哈希中的键之前对数据进行规范化。在这个例子中,我只是把它全部写成小写。

当您使用警告时,您不妨使用warn函数来发出有关错误条件的警告。在实际的应用程序中,您可以在电子邮件警报系统中点击警告,以便随时了解您的无人值守软件何时出现问题。

or + die成语在做文件操作时是非常好的做法。但是,如果包含$ OS_ERROR(a.k.a. $!!),即使是打印,这些死亡也会更多。通过这种方式,您将知道拒绝的权限,不存在的或磁盘已满的差异等。

这些建议涉及编写可维护和有弹性的程序问题。但我个人认为,代码的美学也有助于可维护性。有意义的命名约定和代码格式可以在您从现在起的一两年内打开此程序进行改进或修复错误时产生重大影响。我更喜欢创建缺乏不必要混乱的代码,例如说明明显的注释或使用注释来移除代码块。

保持良好的工作。世界需要更多的软件自动化。

#!/usr/bin/perl 

use strict; 
use warnings; 
use DBI; 

# 
# _voting.pl 
# 
my $logfile = '/var/www/voting/votes.txt'; 

my $errors = 0; 

my %campaign_id_for = (
    'ssss_uk_01b' => 1, 
    'ssss_uk_01c' => 2, 
    'ssss_uk_01d' => 3, 
    'ssss_uk_01e' => 4, 
    'ssss_uk_01f' => 5, 
    'ssss_uk_01g' => 6, 
); 

my %candidate_id_for = (
    'brown' => 1, 
    'cameron' => 2, 
    'balls' => 3, 
    'green' => 4, 
    'boring' => 5, 
    'tupele' => 6, 
); 

my $dbh = DBI->connect( 
    'DBI:mysql:database=sms_voting;host=localhost', 
    'sisisi', 
    '*********', 
    { 'RaiseError' => 1 } 
); 

my $sth = $dbh->prepare(q{ 
    INSERT INTO voting (
     epoch, 
     validity, 
     choice, 
     campaigns_id, 
     candidates_id 
    ) VALUES (
     ?, 
     ?, 
     ?, 
     ?, 
     ? 
    ) 
}); 

my $fh; 

open $fh, '<', $logfile 
    or die "open $logfile: $!"; 

LINE: 
for my $line (<$fh>) { 

    my ($vote, $epoch, $campaign, $validity, $choice, 
     $CONN, $MSISDN, $GUID,  $Shortcode 
    ) = split /\s+/, $line; 

    ($campaign) = reverse split /:/, $campaign; 
    ($validity) = reverse split /:/, $validity; 
    ($choice) = reverse split /:/, $choice; 

    my $campaign_id = $campaign_id_for{ lc $campaign }; 
    my $candidate_id = $candidate_id_for{ lc $choice }; 

    if ($epoch && $validity && $choice && $campaign_id && $candidate_id) { 

     $sth->execute(
      $epoch, 
      $validity, 
      $choice, 
      $campaign_id, 
      $candidate_id 
     ); 

     print "$epoch $validity $choice\n" 
      or die "print: $!"; 

     next LINE; 
    } 
    else { 

     warn "failed to parse: $line\n"; 
     $errors++; 
    } 
} 

close $fh 
    or die "close $logfile: $!"; 

# debug 
print "error count: $errors\n" 
    or die "print: $!"; 
+1

事实上,并且引用:'凡被赋予智慧的人都被赋予了许多善。 – cookie

相关问题