получить последние несколько строк файла, хранящегося в переменной - PullRequest
2 голосов
/ 13 июля 2011

Как я могу получить последние несколько строк файла, который хранится в переменной?В 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?

Ответы [ 4 ]

5 голосов
/ 13 июля 2011

Чтобы прочитать конец файла, 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);

даст вам дескриптор ввода / вывода, который генерирует последние 1000 символов в $the_variable.

4 голосов
/ 13 июля 2011

Модуль File::ReadBackwards на CPAN - это, вероятно, то, что вам нужно.Вы можете использовать это таким образом.Это напечатает последние три строки в файле:

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

Внутренне, он ищет () ближе к концу файла и ищет окончания строк, поэтому он должен быть довольно эффективным с памятью, дажес очень большими файлами.

3 голосов
/ 13 июля 2011

В некоторой степени это зависит от размера файла и количества строк. Если он будет очень большим, вам нужно быть осторожным, потому что чтение всего этого в памяти займет намного больше времени, чем простое чтение последней части файла.

Если оно маленькое. самый простой способ - это, вероятно, File::Slurp поместить его в память, split разделителями записей и сохранить последние n записей. По сути, что-то вроде:

# 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])

Если он большой, слишком большой, чтобы его можно было найти в памяти, лучше использовать операции с файловой системой напрямую. Когда я сделал это, я открыл файл и использовал seek() и прочитал последние 4 КБ или около того файла и повторял назад, пока у меня не было достаточно данных, чтобы получить необходимое мне количество записей.

Не подробный ответ, но вопрос может быть более конкретным.

0 голосов
/ 01 сентября 2017

Я знаю, что это старый вопрос, но я нашел его, когда искал способ поиска шаблона в первой и последней k строках файла.

Для хвостовой части вПомимо seek (если файл доступен для поиска), он экономит некоторую память для использования вращающегося буфера следующим образом (возвращает последние k строк или меньше, если доступно менее $k):

my $i = 0; my @a;
while (<$fh>) {
    $a[$i++ % $k] = $_;
}
my @tail = splice @a,0,$i % $k;
splice @a,@a,0,@tail;
return @a;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...