Удалить первую строку в файле, если она соответствует шаблону - PullRequest
2 голосов
/ 05 февраля 2012

Интересно, есть ли эффективный способ удалить первую строку в файле, если она соответствует заданному шаблону.Например, у меня есть файл с данными следующей формы:

Date,Open,High,Low,Close,Volume,Adj.Volume
2012-01-27,42.38,42.95,42.27,42.68,2428000,42.68
2012-01-26,44.27,44.85,42.48,42.66,5785700,42.66
.
.
.

Я хочу удалить первую строку, только если она содержит текст (как показано в примере в первой строке), иоставьте его без изменений, если он содержит только цифры (как в остальных строках).Эта задача довольно проста, и я выполнил ее, применив следующий код, который записывает каждую строку в $newFile, если она не включает шаблон Date:

while( <$origFile> )
    {
        chomp($_);
        print $newFile $_ unless ($_  =~ m/Date/g)
    }

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

Есть ли способ выполнить эту задачу более эффективно?

ПРИМЕЧАНИЕ: я уже нашел почти такой же вопрос здесь , но, поскольку я хочу, чтобы мой код был доступен и в Linux и Windows, использование sed здесь мне не поможет.

Заранее спасибо!

Ответы [ 3 ]

3 голосов
/ 05 февраля 2012

$. может использоваться для определения, обрабатываются ли первые строки файла.

perl -i.bak -ne'print if $. != 1 || !/^Date/;' file
Однако кажется, что это большая трата ресурсов начитать каждую строку в целом файле

Невозможно удалить из любого места, кроме конца файла.Чтобы удалить из начала или середины, все, что следует в файле, должно быть смещено, что означает, что оно должно быть прочитано и записано.

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

2 голосов
/ 05 февраля 2012

Модуль Tie :: File идеально подходит для этого.Это очень эффективно, поскольку блокирует IO вместо чтения строки за раз, и делает программу очень простой для записи.

use strict;
use warnings;

use Tie::File;

tie my @data, 'Tie::File', 'mydatafile' or die $!;
shift @data if $data[0] =~ /Date/;
untie @data;
1 голос
/ 07 февраля 2012

Выполните тестирование только в первой строке, затем просто запустите остальную часть файла без проверки:

if (defined( $_ = <$origFile> )) {
    if ( ! m/Date/o ) { print $newFile $_ }

    my $data;

    for (;;) {
        my $readRes = read($origFile, $data, 0x10000);

        if (!defined $readRes) { die "Can't read: $!" }

        if ($readRes == 0) { last }

        print $newFile $data;
    }
}
...