在工作中,我们正在开发一个客户可以使用的新闻通讯系统.作为一名实习生,我的工作之一是帮助解决难题中较小的部分.在这种情况下,我需要做的是扫描电子邮件服务器的日志以查找退回的邮件,并添加电子邮件以及电子邮件退回到"错误的电子邮件数据库"的原因.
坏电子邮件表有两列:'email'和'reason'我使用以下语句从日志中获取信息并将其发送到Perl脚本
grep " 550 " /var/log/exim/main.log | awk '{print $5 "|" $23 " " $24 " " $25 " " $26 " " $27 " " $28 " " $29 " " $30 " " $31 " " $32 " " $33}' | perl /devl/bademails/getbademails.pl
如果你对更高效的awk脚本有兴趣,那么我也很高兴听到这些,但我主要关注的是Perl脚本.awk将"foo@bar.com | reason for the buounce"传递给Perl脚本.我想接受这些字符串,将它们拆分为| 并将两个不同的部分放入数据库中各自的列中.这就是我所拥有的:
#!usr/bin/perl use strict; use warnings; use DBI; my $dbpath = "dbi:mysql:database=system;host=localhost:3306"; my $dbh = DBI->connect($dbpath, "root", "******") or die "Can't open database: $DBI::errstr"; while() { my $line = $_; my @list = # ? this is where i am confused for (my($i) = 0; $i < 1; $i++) { if (defined($list[$i])) { my @val = split('|', $list[$i]); print "Email: $val[0]\n"; print "Reason: $val[1]"; my $sth = $dbh->prepare(qq{INSERT INTO bademails VALUES('$val[0]', '$val[1]')}); $sth->execute(); $sth->finish(); } } } exit 0;
Andru Luvisi.. 14
像这样的东西会起作用:
while() { my $line = $_; chomp($line); my ($email,$reason) = split(/\|/, $line); print "Email: $email\n"; print "Reason: $reason"; my $sth = $dbh->prepare(qq{INSERT INTO bademails VALUES(?, ?)}); $sth->execute($email, $reason); $sth->finish(); }
您可能会发现在Perl中执行整个操作更容易."除非/ 550 /"可以取代grep,正则表达式可能会取代awk.
像这样的东西会起作用:
while() { my $line = $_; chomp($line); my ($email,$reason) = split(/\|/, $line); print "Email: $email\n"; print "Reason: $reason"; my $sth = $dbh->prepare(qq{INSERT INTO bademails VALUES(?, ?)}); $sth->execute($email, $reason); $sth->finish(); }
您可能会发现在Perl中执行整个操作更容易."除非/ 550 /"可以取代grep,正则表达式可能会取代awk.
我不确定你要把什么放在@list中?如果awk为每个条目管道一行,那么你将在$ line中使用它,并且你不需要@list上的for循环.
也就是说,如果你要将它传输到Perl中,为什么首先要使用grep和AWK呢?
#!/ust/bin/perl -w use strict; while (<>) { next unless / 550 /; my @tokens = split ' ', $_; my $addr = $tokens[4]; my $reason = join " ", @tokens[5..$#tokens]; # ... DBI code }
关于DBI调用的旁注:您应该使用占位符,以便"错误的电子邮件"无法将SQL注入您的数据库.
为什么不放弃grep和awk直接去Perl?
免责声明:我还没有检查以下代码是否编译:
while () { next unless /550/; # skips over the rest of the while loop my @fields = split; my $email = $fields[4]; my $reason = join(' ', @fields[22..32]); ... }
编辑:请参阅@ dland的评论进一步优化:-)
希望这可以帮助?
您是否考虑过使用App :: Ack?您可以只使用Perl而不是外壳程序.不幸的是,你必须仔细阅读ack程序代码才能真正了解如何做到这一点,但你应该得到一个更便携的程序.