Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法使用Perl从大小为~2GB的文件中读取某些单词的计数_Perl_Shell - Fatal编程技术网

无法使用Perl从大小为~2GB的文件中读取某些单词的计数

无法使用Perl从大小为~2GB的文件中读取某些单词的计数,perl,shell,Perl,Shell,我已经编写了一个Perl程序,它将匹配日志文件中的某些单词,并将结果存储在数据库中。问题是,这个程序可以很好地处理小文件,但不能处理大小为2GB的文件。是否需要更改尺寸或程序 use POSIX qw(strftime); # load module use DBI; open( FILE, "/root/temp.log" ) or die "Unable to open logfile:$!\n"; $count_start = 0; $count_interim = 0; $cou

我已经编写了一个Perl程序,它将匹配日志文件中的某些单词,并将结果存储在数据库中。问题是,这个程序可以很好地处理小文件,但不能处理大小为2GB的文件。是否需要更改尺寸或程序

use POSIX qw(strftime);

# load module
use DBI;

open( FILE, "/root/temp.log" ) or die "Unable to open logfile:$!\n";
$count_start   = 0;
$count_interim = 0;
$count_stop    = 0;

while (<FILE>) {
  @test = <FILE>;
  foreach $line (@test) {

    if ( $line =~ m/server start/ ) {

      #print "yes\n";
      $count_start++;
    }
    elsif ( $line =~ m/server interim-update/ ) {
      $count_stop++;
    }
    elsif ( $line =~ m/server stop/ ) {
      $count_interim++;
    }

  }
  print "$count_start\n";
  print "$count_stop\n";
  print "$count_interim\n";
  $now_string = strftime "%b %e %H:%M:%S", localtime;
  print $now_string;

  # connect
  my $dbh = DBI->connect( "DBI:Pg:dbname=postgres;host=localhost",
    "postgres", "postgres", { 'RaiseError' => 1 } );

  # execute INSERT query
  my $rows = $dbh->do(
"insert into radcount (acc,bcc,dcc) Values  ('$count_start','$count_stop','$count_interim')"
  );

  print "$rows row(s) affected\n";

  # clean up
  $dbh->disconnect();

}

close(LOG);
使用POSIXQW(strftime);
#加载模块
使用DBI;
打开(文件“/root/temp.log”)或死“无法打开日志文件:$!\n”;
$count\u start=0;
$count_中期=0;
$count_stop=0;
而(){
@测试=;
foreach$行(@test){
如果($line=~m/server start/){
#打印“是”\n;
$count_start++;
}
elsif($line=~m/服务器临时更新/){
$count_stop++;
}
elsif($line=~m/server-stop/){
$count_临时++;
}
}
打印“$count\u start\n”;
打印“$count\u stop\n”;
打印“$count\u middial\n”;
$now\u string=strftime“%b%e%H:%M:%S”,localtime;
打印$now\u字符串;
#连接
my$dbh=DBI->connect(“DBI:Pg:dbname=postgres;host=localhost”,
“postgres”、“postgres”、{'RaiseError'=>1});
#执行插入查询
我的$rows=$dbh->do(
“在radcount(acc、bcc、dcc)值中插入(‘$count_开始’、‘$count_停止’、‘$count_中间’)”
);
打印“$行受影响的行\n”;
#清理
$dbh->disconnect();
}
关闭(日志);

这里有几件事-首先,我建议将文件句柄更改为三个arg open-推理


open(我的$fileHandle),这里有几件事-首先,我建议将文件句柄更改为三个arg-open-推理


open(my$fileHandle),我对您的程序有一些评论

  • 始终在程序开始时
    使用strict
    使用warnings
    ,并在变量首次使用时使用
    my
    声明变量

  • 始终使用词法文件句柄和三参数形式的
    open
    ,并始终检查打开调用的状态

  • 您正在使用文件句柄
    文件
    打开文件,但正在关闭
    日志

  • 您的
    while
    语句读取文件的第一行并将其丢弃

  • @test=
    尝试将文件的其余部分全部读取到数组中。这就是导致问题的原因

  • 您应该连接到数据库一次,并在代码的其余部分使用相同的数据库句柄

  • 您应该使用带有占位符的
    prepare
    语句,并使用
    execute

  • 对于
    临时更新
    记录,您正在增加
    $count\u stop
    ;对于
    停止
    记录,您正在增加
    $count\u transition

  • 核心模块
    Time::Piece
    提供了一种
    strftime
    方法,而不需要
    POSIX

这里是你的程序的一个修改来展示这些想法。我还没有设置日志文件和数据库来测试它,但它看起来很好,并且可以编译

use strict;
use warnings;

use Time::Piece;
use DBI;

open my $log, '<', '/root/temp.log' or die "Unable to open log file: $!";

my ($count_start, $count_interim, $count_stop) = (0, 0, 0);

while (<$log>) {

  if ( /server start/ ) {
    $count_start++;
  }
  elsif ( /server interim-update/ ) {
    $count_interim++;
  }
  elsif ( /server stop/ ) {
    $count_stop++;
  }
}

print <<END;
Start:   $count_start
Interim: $count_interim
Stop:    $count_stop
END

print localtime->strftime("%b %e %H:%M:%S"), "\n";

my $dbh = DBI->connect(
    "DBI:Pg:dbname=postgres;host=localhost", "postgres", "postgres",
    { 'RaiseError' => 1 } );

my $insert = $dbh->prepare('INSERT INTO radcount (acc, bcc, dcc) VALUES (?, ?, ?)');
my $rows = $insert->execute($count_start, $count_stop, $count_interim);

printf "%d %s affected\n", $rows, $rows == 1 ? 'row' : 'rows';
使用严格;
使用警告;
使用时间::件;
使用DBI;

打开我的$log,“我对你的程序有一些评论

  • 始终在程序开始时
    使用strict
    使用warnings
    ,并在变量首次使用时使用
    my
    声明变量

  • 始终使用词法文件句柄和三参数形式的
    open
    ,并始终检查打开调用的状态

  • 您正在使用文件句柄
    文件
    打开文件,但正在关闭
    日志

  • 您的
    while
    语句读取文件的第一行并将其丢弃

  • @test=
    尝试将文件的其余部分全部读取到数组中。这就是导致问题的原因

  • 您应该连接到数据库一次,并在代码的其余部分使用相同的数据库句柄

  • 您应该使用带有占位符的
    prepare
    语句,并使用
    execute

  • 对于
    临时更新
    记录,您正在增加
    $count\u stop
    ;对于
    停止
    记录,您正在增加
    $count\u transition

  • 核心模块
    Time::Piece
    提供了一种
    strftime
    方法,而不需要
    POSIX

这里是你的程序的一个修改来展示这些想法。我还没有设置日志文件和数据库来测试它,但它看起来很好,并且可以编译

use strict;
use warnings;

use Time::Piece;
use DBI;

open my $log, '<', '/root/temp.log' or die "Unable to open log file: $!";

my ($count_start, $count_interim, $count_stop) = (0, 0, 0);

while (<$log>) {

  if ( /server start/ ) {
    $count_start++;
  }
  elsif ( /server interim-update/ ) {
    $count_interim++;
  }
  elsif ( /server stop/ ) {
    $count_stop++;
  }
}

print <<END;
Start:   $count_start
Interim: $count_interim
Stop:    $count_stop
END

print localtime->strftime("%b %e %H:%M:%S"), "\n";

my $dbh = DBI->connect(
    "DBI:Pg:dbname=postgres;host=localhost", "postgres", "postgres",
    { 'RaiseError' => 1 } );

my $insert = $dbh->prepare('INSERT INTO radcount (acc, bcc, dcc) VALUES (?, ?, ?)');
my $rows = $insert->execute($count_start, $count_stop, $count_interim);

printf "%d %s affected\n", $rows, $rows == 1 ? 'row' : 'rows';
使用严格;
使用警告;
使用时间::件;
使用DBI;

打开我的$log,'还有,
使用strict
使用warnings
!和
使用autodie
!是的,我肯定应该提到这些,谢谢你把它捡起来哦,
使用DateTime::TimeZone
可能也是个好主意,我想我不确定
autodie
DateTime
…好的。它很有效是的。我想的更多的是认真。另一件不太好的事情是没有[
DBI
-placeholder](search.cpan.org/~timb/DBI/DBI.pm#placeholder_和(u Bind)值)我也会考虑这个坏的风格。但是我们应该把它放在这个问题的评论中,而不是你的答案,这很好。也许有一些潜在的诡计(取决于他们对他们存储的数据的期望)。当下一个闰日|秒或DST来临时,没有使用时间模块来处理这类问题。你肯定在这里做出了最明智的评论-在这个问题上把它们扔掉!而且,
使用严格的
使用警告
!和
使用autodie
!是的,我肯定应该提到这些,谢谢你的帮助我想我也不太清楚如何使用autodie
DateTime
…好吧。它的工作原理是这样的。我是
use strict;
use warnings;

use Time::Piece;
use DBI;

open my $log, '<', '/root/temp.log' or die "Unable to open log file: $!";

my ($count_start, $count_interim, $count_stop) = (0, 0, 0);

while (<$log>) {

  if ( /server start/ ) {
    $count_start++;
  }
  elsif ( /server interim-update/ ) {
    $count_interim++;
  }
  elsif ( /server stop/ ) {
    $count_stop++;
  }
}

print <<END;
Start:   $count_start
Interim: $count_interim
Stop:    $count_stop
END

print localtime->strftime("%b %e %H:%M:%S"), "\n";

my $dbh = DBI->connect(
    "DBI:Pg:dbname=postgres;host=localhost", "postgres", "postgres",
    { 'RaiseError' => 1 } );

my $insert = $dbh->prepare('INSERT INTO radcount (acc, bcc, dcc) VALUES (?, ?, ?)');
my $rows = $insert->execute($count_start, $count_stop, $count_interim);

printf "%d %s affected\n", $rows, $rows == 1 ? 'row' : 'rows';