Загляните в следующую строку, но не потребляйте ее

getline читает следующую строку и увеличивает счетчик NR на 1. После использования getline awk возобновляет работу со следующей строки. Это желаемое поведение в большинстве случаев.

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

Как я могу вернуться на одну строку в awk? Я попытался установить счетчик NR вручную на NR=NR-1, но это не сработало. Или есть метод, который смотрит только на следующую строку, не меняя NR?

Мне нужен просмотр вперед на одну строку. Простое сохранение строки в переменной и обращение к ней позже не работает в этом случае. Я пытаюсь реализовать грамотный инструмент программирования в awk, где мастер-файл может содержать множество подфайлов. Такой подфайл начинается со строки типа "% file:file1". Конец такого файла достигается, если достигнута строка с меньшим отступом или другая строка со строкой типа "% file:file2".

Набор правил для всех строк, соответствующих /% file:/, не используется, когда я уже прочитал эту строку с помощью getline. Вот почему я хотел бы сбросить NR на предыдущую строку, тогда awk снова прочитает строку, соответствующую /% file:/, и будет выполнено соответствующее правило.


person Chris    schedule 19.04.2012    source источник
comment
Я разработал текстовый язык под названием TXR, в котором реализовано сопоставление с образцом с неявным возвратом как в линейно-ориентированном (вертикальном), так и в символьно-ориентированном (горизонтальном) режимах сопоставления. Упреждающая глубина — это произвольное количество символов или строк. TXR почти идеален для обработки грамотной нотации программирования. Трудно привести прямо относящийся к делу пример; можете выложить полную спецификацию грамотной нотации?   -  person Kaz    schedule 20.04.2012


Ответы (2)


Это может приблизиться к тому, что вы ищете, и не должно быть таким же дорогим, как решение sed, поскольку AWK поддерживает указатель на файл, который открывается getline.

awk 'FNR == 1 {
         getline nextline < FILENAME
     }
     {
         getline nextline < FILENAME;
         print "currentline is:", $0;
         print "nextline is:   ", nextline
     }' input file

Первый блок читает первую строку и теряет ее.

В этой форме getline не устанавливает никаких переменных, таких как NR, FNR, NF или $0. Он устанавливает только переменную, которую вы указываете (в данном случае nextline).

Дополнительную информацию см. в этом.

person Dennis Williamson    schedule 20.04.2012
comment
Позор, похоже, это специфично для GNU awk. - person 0xC0000022L; 16.05.2014
comment
Я проверил ваш метод с помощью следующей команды for i in {1..10} ; do echo $i ; done > tesxt2.txt && awk --posix '{getline var < FILENAME ; print var,$i}' tesxt2.txt && rm tesxt2.txt К сожалению, getline не смог показать следующую строку. Это из-за отсутствия FNR == 1? - person Alexander Cska; 27.03.2019
comment
@DennisWilliamson спасибо за быстрый ответ. К сожалению, нет, print var,$i показал те же самые переменные (1,1, 2,2 и т. д.). Это должно быть print var,$0, но в обоих случаях вывод не захватывает new & old строку - person Alexander Cska; 27.03.2019
comment
@AlexanderCska: Проблема в том, что в вашем скрипте awk печатает var,$i, а i не установлено. Если бы это было так, он напечатал бы поле i из-за знака доллара. Вместо этого он должен напечатать var,$0. Просто случается так, что неустановленный i интерпретируется как ноль, и поэтому кажется, что он делает то, что вы намеревались. Но главная проблема в вашем тесте в том, что вы не включили первый блок из моего ответа (FNR == 1 { ... }). - person Dennis Williamson; 27.03.2019

Это немного хак и довольно дорого, но для небольших файлов дает вам возможность заглянуть вперед:

cmd="sed -n " NR + 1 "p " FILENAME; cmd | getline nextline

Это примет текущее значение NR и использует sed для извлечения строки NR + 1 из входного файла. Это дорого, потому что sed будет считывать весь файл каждый раз, когда вы выполняете предварительный просмотр (вы можете немного облегчить это, добавив команду 'q' к sed). Переменная nextline будет установлена ​​на следующую строку файла и будет пустой в последней строке.

person William Pursell    schedule 19.04.2012