Как мне обработать файл двумя строками за раз в Perl? - PullRequest
2 голосов
/ 26 ноября 2011

У меня есть файл сигнала, каждая строка которого начинается с 0 или 1.

Если у меня 1, а затем 0 в следующей строке, то мне нужно обработать сигнальную строку 0.

>#Sample File

>0

>0

>1

>0 (process line)

>0

>1

>0 (process line)
мой код
 OUTER : while (<F>) {
   if($_=~/1/){
     my $a = <F>
     process_line($a) if ($a=~/0/);
     next OUTER if ($a=~/1/);
   }

Файл огромный, поэтому я не хочу хлебать.

Ответы [ 3 ]

4 голосов
/ 26 ноября 2011

Что-то вроде:

#!/usr/bin/perl

use strict;
use warnings;
my $prevLine = "";

sub processline {
    my $line = shift;
    $line =~ s@^0 @@;
    print $line;
}

while (<DATA>) {
    if ($_ =~ /^0/ && $prevline =~ /^1/) {
        processline($_);
    }
    $prevLine = $_;
}

__DATA__
0
0
1
0 (process line)
0
1
0 (process line)

выход

(process line)
(process line)
1 голос
/ 26 ноября 2011

Я вижу возможную ошибку в вашем коде: две или более последовательных строки, начинающиеся с 1, пропускаются и пропускаются совпадения.

while (<>) {
   if(/^1/){            # Ignore everything except 1-lines
      while (<>) {      # Start inner loop
         next if /^1/;  # Skipping consecutive 1-lines
         die "Bad line: $_" unless /^0/;  # Anything not 1 or 0 is not allowed
         process_line($_);
         last;          # Exit inner loop, search for next 1-line
      }
   }
}

Параметры использования:

script.pl filename        (single file)
script.pl filename*       (glob, multiple files)
some_command | script.pl

Изменения:

  • Глобальный дескриптор файла изменен на оператор diamond, работает с STDIN или аргументами имени файла в сценарии.Если вы хотите явное открытие, используйте open my $fh, '<', $filename or die $!
  • Добавлены якоря в регулярных выражениях для соответствия только началу строки, например, /^1/
  • Удалена ненужная метка OUTER.next и last влияют только на самый внутренний цикл (см. perldoc -f last ).
  • $_ =~ /^1/ изменено на /^1/, что эквивалентно и более разборчиво.
  • Вложенное использование $_ допустимо и будет работать как положено.Если хотите, внутренний цикл может использовать другую переменную, например, while (my $line = <>), которая может показаться некоторым менее запутанной.(Не для меня, однако)

Вы должны использовать строгие и предупреждения, если вы еще этого не делаете. Зачем использовать строгие и предупреждения?

0 голосов
/ 26 ноября 2011

Еще один вариант:

#!/usr/bin/env perl
use strict;
use warnings;
sub processme {
    my $line = shift;
    print $line;
}
while (<>) {
    if (/^1/../^0/) {
        processme( $_ ) if /^0/;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...