我有以下简单的脚本:
my $filename = './log_file';
my $file;
open(FILE, "$filename") or die "Cant open $filename\n";
local $/ = undef;
$file = <FILE>;
close(FILE);
my $regexp = 'Something\n';
print "OK\n" if ($file =~ m{$regexp}msg);
log_file的内容是:
Something
Nothing
Nothing
Nothing
Nothing
.
.
.
当log_file的大小为2GB时,脚本打印OK。 但是当它的大小是2.1GB或更多时,它打印不正常。 谁知道为什么?以及如何解决这个问题?我不想拆分文件,因为我的正则表达式是多行
答案 0 :(得分:4)
将文件加载到变量中时,将整个文件读入内存。这可能会导致您的内存超过2GB(取决于系统资源)。另外,根据您的操作系统可能会遇到引擎下的大文件处理问题(特别是在32位系统上),在unix上结帐“man largefile”,这将以2GB开始。
考虑到大小,最好在循环中一次读取行或块,而不是啜饮整个事物。也许在阅读文件时使用滚动的2(或更多)行窗口来处理多行匹配。
答案 1 :(得分:1)
您的perl可能无法在启用USE_LARGE_FILES
的情况下进行编译,这会将文件大小限制为2 gigs。您可以使用以下命令验证此操作,例如check:
$perl -V:uselargefiles
uselargefiles='define';
正如dethorpe已经建议的那样,无论如何,修改脚本以逐行处理,或者如果要跨多行测试,然后使用缓冲区,可能是明智的。
以下是如何使用5行缓冲区测试多行正则表达式的示例:
use strict;
use warnings;
my @buffer;
while (<DATA>) {
push @buffer, $_;
if (@buffer == 5 || eof) {
my $buffer = join '', @buffer;
while ($buffer =~ m{([a-z]+)\n(\d+)}g) {
# Truncate buffer for match found
@buffer = substr $buffer, pos $buffer;
print "$1\n";
}
shift @buffer;
}
}
__DATA__
1
2
3
4
5
6
7
abc
123
10
def
456 ghi
789
13
14
15
16
输出
abc
def
ghi