Может кто-нибудь дать некоторые подсказки о том, как удалить последние n строк из файла на Perl? У меня очень большой файл размером около 400 МБ, и я хочу удалить из него 125 000 последних строк.Как удалить последние N строк файла?
ответ
Вы можете использовать Tie::File для обработки файла в виде массива.
use Tie::File; tie (@File, 'Tie::File', $Filename); splice (@File, -125000, 125000); untie @File;
В качестве альтернативы можно использовать head
и wc -l
в оболочке.
редактировать: grepsedawk не напоминает нам о -n
опции к head
, не wc
необходимо:
head -n -125000 FILE > NEWFILE
+1 Мне нравится идея оболочки. Это было бы моим первоначальным подходом. Особенно, если это одно. – 2008-12-05 23:44:12
Да, я просто использовал wc и head, и кажется, что это работает .. :) – anand 2008-12-05 23:48:18
На самом деле, я думаю, что в этом случае скрипт perl масштабируется лучше, потому что он не пишет файл заново. – Svante 2008-12-05 23:54:34
Вы знаете, сколько строк есть, или есть какой-либо другой ключ об этом файле? Вам нужно сделать это снова и снова, или это один раз?
Если бы я должен был сделать это один раз, я бы загрузить файл в Vim, посмотрите на последний номер строки, а затем удалить из последней строки, я не хочу до конца:
:1234567,$d
Общее программирование путь состоит в том, чтобы сделать это в два прохода: один, чтобы определить количество строк, а затем один, чтобы избавиться от линий.
Простым способом является печать правильного количества строк в новый файл. Он эффективен только с точки зрения циклов и, возможно, немного разбивается диск, но у большинства людей их много. Некоторые из вещей в perlfaq5 должны помочь. Вы выполняете свою работу, и вы продолжаете жить.
while() { print $out; last if $. > $last_line_I_want; }
Если это то, что вам нужно сделать много или размер данных слишком велик, чтобы переписать его, вы можете создать индекс линий и смещения байта и truncate() файл в нужный размер. Поскольку вы сохраняете индекс, вам нужно только открыть новые строки, потому что вы уже знаете, где вы остановились. Некоторые модули обработки файлов могут обрабатывать все это для вас.
- идти до конца файла: FSEEK
- счета в обратном направлении, что многие линии
- выяснить позицию файла: ftell
- усечь файл в таком положении, как длина: ftruncate
Я бы просто использовал сценарий оболочки для этой проблемы:
tac file | sed '1,125000d' | tac
(tac похож на кошку, но печатает строки в обратном порядке. Джей Лепре и Дэвид Маккензи. Часть GNU coreutils.)
Наиболее эффективным способом является поиск конца файла, затем постепенное считывание сегментов при подсчете количества строк в каждой, а затем использование усечения (см. Perldoc -f truncate) чтобы обрезать его. В CPAN также есть модуль или два для чтения файла назад.
Как уже было сказано, Tie :: Array, который хорошо выполняет эту работу, я изложу основной алгоритм, если вы хотите сделать это вручную. Есть неаккуратные, медленные способы сделать это, которые хорошо работают для небольших файлов.Вот эффективный способ сделать это для больших файлов.
- Найти позицию в файле непосредственно перед N-й строкой с конца.
- Обрезать все после этой точки (используя
truncate()
).
1 является сложной частью. Мы не знаем, сколько строк в файле или где они находятся. Один из способов - подсчитать все линии, а затем вернуться к Nth. Это означает, что мы должны каждый раз сканировать весь файл. Более эффективным было бы чтение назад с конца файла. Вы можете сделать это с помощью read()
, но проще использовать File::ReadBackwards, который может идти в обратном направлении за строкой (при использовании эффективных буферизованных чтений).
Это означает, что вы читаете всего 125 000 строк, а не весь файл. truncate()
должен быть O (1) и атомарным и стоить почти ничего, независимо от размера файла. Он просто сбрасывает размер файла.
#!/usr/bin/perl
use strict;
use warnings;
use File::ReadBackwards;
my $LINES = 10; # Change to 125_000 or whatever
my $File = shift; # file passed in as argument
my $rbw = File::ReadBackwards->new($File) or die $!;
# Count backwards $LINES or the beginning of the file is hit
my $line_count = 0;
until($rbw->eof || $line_count == $LINES) {
$rbw->readline;
$line_count++;
}
# Chop off everything from that point on.
truncate($File, $rbw->tell) or die "Could not truncate! $!";
Schwern: Нужны ли use Fnctl
и $rbw->get_handle
строки в вашем скрипте? Кроме того, я бы рекомендовал сообщить об ошибках truncate
в случае, если он не вернет true.
- Дуглас Хантер (кто бы прокомментировал этот пост, если он мог бы)
Попробуйте этот код:
мой $ я = 0;
sed -i '\ $ d' имя файла while ($ i ++ < n);
также обратные кавычки будут там, но я не смог получить их напечатанный :(
попробовать этот
:|dd of=urfile seek=1 bs=$(($(stat -c%s urfile)-$(tail -1 urfile|wc -c)))
Мое предложение, используя ed
:
printf '$-125000,$d\nw\nq\n' | ed -s myHugeFile
Этот пример код будет содержать индекс последних 10 строк, поскольку он сканирует файл. Затем он использует самый ранний индекс i n буфер, чтобы усечь файл. Это, конечно, будет работать, только если усечение работает в вашей системе.
#! /usr/bin/env perl
use strict;
use warnings;
use autodie;
open my $file, '+<', 'test.in'; # rw
my @list;
while(<$file>){
if(@list <= 10){
push @list, tell $file;
}else{
(undef,@list) = (@list,tell $file);
}
}
seek $file, 0, 0;
truncate $file, $list[0] if @list;
close $file;
Это имеет дополнительное преимущество, что она использует только до достаточно памяти для последних десяти индексов и текущей строки.
- 1. удалить последние N строк из файла bash
- 2. Java: прочитайте последние n строк ОГРОМНОГО файла
- 3. Как удалить последние 5 строк файла
- 4. C Удалить последние n символов из файла
- 5. Удалить последние N байтов из файла
- 6. GDB - показывать последние n строк
- 7. Как распечатать последние n строк файла с помощью C?
- 8. как читать последние n строк из файла в C
- 9. PHP: Как удалить последние N байтов из большого файла?
- 10. Как читать последние «n» строки файла журнала
- 11. Удалить последние N элементов списка
- 12. Удалить последние n строк (предложений) в String в Java
- 13. Как удалить последние n символов из строки?
- 14. JQuery загружает только последние n строк страницы
- 15. Простой способ НЕ читать последние N строк файла в Python
- 16. Как удалить последние n строк в файле с помощью файла bash?
- 17. Чтение последних n строк файла
- 18. Как я могу заставить свой скрипт bash удалить первые n и последние n строк из переменной? `
- 19. Выбрать последние N строк следующие условия
- 20. Выберите последние N строк SQL Server 2012
- 21. Удалить последние «\ n» из текстового поля
- 22. удалить последние n букв из в javascript
- 23. захватить последние n строк из вывода консоли
- 24. Как удалить последние N строк из csv, используя R, когда общее количество строк может измениться?
- 25. распечатать последние 10 строк файла
- 26. Как удалить n строк из txt-файла в R?
- 27. Ruby, удалить последние N символов из строки?
- 28. Удалить последние N записей, Entity Framework
- 29. удалить последние 10 символов файла
- 30. Как читать последние n строк HUGE сжатого файла без распаковки всего файла на диск
Это должно было быть faq. Подождите, подождите минуту. * type type type совершить *. Теперь это в perlfaq5. :) – 2009-10-20 07:02:40