获取存储在变量中的最后几行文件

时间:2011-07-12 21:01:42

标签: perl

如何获取存储在变量中的文件的最后几行?在linux上我会使用tail命令,如果它在文件中。

1) How can I do this in perl if the data is in a file?
2) How can I do this if the content of the file is in a variable?

5 个答案:

答案 0 :(得分:5)

要读取文件末尾,seek靠近文件末尾并开始阅读。例如,

open my $fh, '<', $file;
seek $fh, -1000, 2;
my @lines = <$fh>;
close $fh;

print "Last 5 lines of $file are: ", @lines[-5 .. -1];

根据文件中的内容或您想要查看的行数,您可能需要使用与上述-1000不同的幻数。

您可以使用变量执行类似操作

open my $fh, '<', \$the_variable;
seek $fh, -1000, 2;

或只是

open my $fh, '<', \substr($the_variable, -1000);

将为您提供一个I / O句柄,在$the_variable中生成最后1000个字符。

答案 1 :(得分:4)

CPAN上的File::ReadBackwards模块可能就是您想要的。你可以这样使用它。这将打印文件中的最后三行:

use File::ReadBackwards
my $bw = File::ReadBackwards->new("some_file");
print reverse map { $bw->readline() } (1 .. 3);

在内部,它搜索()s接近文件的末尾并查找行结尾,因此即使文件非常大,内存也应该相当高效。

答案 2 :(得分:3)

在某种程度上,这取决于文件的大小,以及您想要的行数。如果它会非常大,你需要小心,因为将它全部读入内存将比阅读文件的最后部分花费更长的时间。

如果它很小。最简单的方法可能是File::Slurp通过记录分隔符split进入内存,# first line if not yet in a string my $string = File::Slurp::read_file($filename); my @lines = split(/\n/, $string); print join("\n", @lines[-10..-1]) ,并保留最后n条记录。实际上,类似于:

seek()

如果它很大,太大而无法找到内存,那么最好直接使用文件系统操作。当我这样做时,我打开文件并使用{{1}}并读取文件的最后4k左右,然后向后重复,直到我有足够的数据来获取我需要的记录数。

不是一个详细的答案,但问题可能更具体。

答案 3 :(得分:0)

我知道这是一个老问题,但我找到了一种方法来搜索文件的第一行和最后k行中的模式。

对于尾部,除seek之外(如果文件是可搜索的),它会节省一些内存以使用旋转缓冲区,如下所示(返回最后的k行,如果少于{{则返回更少) 1}}可用):

$k

答案 4 :(得分:0)

文件方面已经说明了很多,但如果它已经在字符串中,您可以使用以下正则表达式:

my ($lines) = $str ~= /
(
 (?:
  (?:(?<=^)|(?<=\n)) # match beginning of line (separated due to variable lookbehind limitation) 
  [^\n]*+            # match the line
  (?:\n|$)           # match the end of the line
 ){0,5}+             # match at least 0 and at most 5 lines
)$                   # match must be from end of the string
/sx                  # s = treat string as single line
                     # x = allow whitespace and comments

这运行得非常快。与 split/join 方法相比,基准测试显示速度提高了 40-90%(由于机器上的当前负载而变化)。这大概是由于较少的内存操作。如果速度是必不可少的,您可能需要考虑的事情。否则,它只是有趣。