Как мне читать абзацы за раз с помощью Perl?

StackOverflow https://stackoverflow.com/questions/1809469

  •  05-07-2019
  •  | 
  •  

Вопрос

Когда я пишу

#!/usr/bin/perl -w
use strict;

while( <DATA> ) {
    print "\n-------------------------\n\n";
    print;
    <>;
}

после каждого "возврата" я получаю одну строку.

Почему я не могу использовать следующий скрипт после каждого "возврата" одного абзаца?

#!/usr/bin/perl -w
use strict;

local $/ = "";

while( <DATA> ) {
    print "\n-------------------------\n\n";
    print;
    <>;
}

__DATA__
line one
line two
line three
line four
line five

line six
line seven
line eigth
line nine

line ten
line eleven
line twelve
Это было полезно?

Решение

В вашем первом скрипте с переменной $ / переменная по умолчанию " \ n " ;, < DATA > будет возвращать только одну строку за раз.

Я полагаю, что второй скрипт делает то, что вы хотите, просто < > не прекращает чтение при возврате, а при < ctrl-d > из-за ваших настроек $ / (как кто-то указал < > читает из STDIN, но я думаю, что вы уже знаете это и используете его для регулирования вывода).

Если вы действительно хотите регулировать вывод с помощью return, вам нужно сделать больше с $ / в цикле.

while( <DATA> ) {
    print "\n-------------------------\n\n";
    print;
    $/ = "\n"; # default so that the following terminates the read on 'return'
    <>;
    $/ = ""; 
}   

Другие советы

Я думаю, вы ожидаете этой реплики

local $/ = "";

чтобы изменить поведение

<DATA>

продолжать чтение до конца данных.

Но на самом деле для этого требуется что-то вроде этого

{
    local $/;  # $/ becomes undef in this block
    ...
}

чтобы включить режим чавканья (и содержать этот режим в области видимости внутри {curlys}).

По сути, это говорит о том, что "забудьте думать о новых строках как о маркере конца записи".,

Кроме этого...там есть ничейный боец в вашем коде!

while( <DATA> ) {
    print "\n-------------------------\n\n";
    print;
    <>;    # <-- Feel the power of the DARK SIDE!!!
}

Этот маленький парень будет читать из STDIN, а не из DATA - это действительно то, чего вы хотите?

Использование < > этот способ (в интерактивном режиме) в режиме абзаца будет сбивать с толку. Он не вернется, когда вы нажмете & Quot; return & Quot ;; вместо этого он будет читать, пока не получит непустую строку (начало абзаца), затем будет считан, пока не получит пустую строку (конец этого абзаца), затем продолжит чтение, пока не получит непустую строку (начало следующего абзаца - который будет буферизован, а не возвращен), поэтому он знает, что он отбрасывает все лишние пустые строки.

Возможно, вам следует использовать:

local $/ = "\n"; <>

вместо этого в конце вашего цикла. Или, может быть, POSIX :: getchar ().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top