0

我正在读取日志文件,这些文件可以是从小日志文件到 8-10mb 日志的任何内容。典型的大小可能是 1mb。现在的关键是,我要查找的关键字通常位于文档末尾附近,在大约 95% 的情况下。然后我在关键字之后提取 1000 个字符。

如果我使用这种方法:

$lines = explode("\n",$body);
$reversed = array_reverse($lines);
foreach($reversed AS $line) {
// Search for my keyword
}

它会比使用更有效:

$pos = stripos($body,$keyword);  
$snippet_pre = substr($body, $pos, 1000);

我不确定的是stripos是否只是一次开始搜索文档1个字符,所以理论上如果关键字后面有10,000个字符,那么我不必将它们读入内存,而第一个选项必须将所有内容读入内存,即使它可能只需要最后 100 行,我是否可以将其更改为将 100 行读入内存,然后如果前 100 行不成功,或者查询太轻以至于它不是真的那么搜索另外 101-200 行事情。

我有第二个问题,假设 reverse_array 是最好的方法,我如何在找到关键字后提取接下来的 1000 个字符,这是我的悲惨尝试

$body = $this_is_the_log_content;

$lines = explode("\n",$body);
$reversed = array_reverse($lines);
foreach($reversed AS $line) {

$pos = stripos($line,$keyword);  
$snippet_pre = substr($line, $pos, 1000);

}

Why i don't think that will work is because each $line might only be a few hundred characters so would the better solution be to explode it every say 2,000 lines and also keep the previous $line as a backup variable so something like this.

$body = $this_is_the_log_content;

$lines = str_split($body, 2000);
$reversed = array_reverse($lines);
$previous_line = $line;
foreach($reversed AS $line) {

$pos = stripos($line,$keyword);  
    if ($pos) {
    $line = $previous_line . ' ' . $line;
    $pos1 = stripos($line,$keyword); 
    $snippet_pre = substr($line, $pos, 1000);
    }

}

我可能大大过度复杂化了这个?

4

1 回答 1

0

我会强烈考虑使用这样的工具grep。您可以从 PHP 调用此命令行工具,并使用它在文件中搜索您要查找的单词,并执行诸如为您提供匹配行的字节偏移量、为您提供匹配行加上尾随上下文行等操作。

这是 grep 手册的链接。 http://unixhelp.ed.ac.uk/CGI/man-cgi?grep

在命令行上稍微玩一下命令以按照您想要的方式获取它,然后根据您需要捕获/显示内容的方式从 PHP 使用 、 或类似exec()方法调用它。passthru()

或者,您可以简单地fopen()将指针放在末尾的文件,然后在文件中向前移动文件指针,在fseek()您移动时使用搜索字符串。一旦找到针,您就可以从该偏移量读取文件,直到到达文件末尾或日志条目数。

其中任何一个都可能比将整个日志文件读入内存然后尝试使用它更可取。

要考虑的另一件事是 1000 个字符是否有意义。通常日志文件会有长度不同的行。对我来说,您似乎应该更关心从日志文件中获取接下来的 X 行,而不是接下来的 Y 个字符。如果一行有 2000 个字符,你是说你只想得到一半吗?那可能根本没有意义。

于 2013-07-24T19:07:33.613 回答