В awk, вы можете использовать шаблон и блок END вместе? - PullRequest
0 голосов
/ 02 января 2019

В awk вы можете выполнить действие для данного шаблона, например:

echo foo | awk '/foo/ {print "foo"}'

или вы можете выполнить действие в конце ввода, например:

echo foo | awk 'END {print "END"}'

Но, кажется, невозможно сделать и то и другое, например:

# echo foo | awk '/foo/ || END {print "foo or END"}'
awk: syntax error at source line 1
 context is
    /foo/ || >>>  END <<<  {print "foo or END"}
awk: bailing out at source line 1

Возможно ли это?

Ответы [ 4 ]

0 голосов
/ 03 января 2019

Нет, вы не можете делать такие вещи. Операторы END выполняются после обработки последней строки и, подобно BEGIN, представляют собой специальные формы шаблонов.

Общая структура программы

Программа awk состоит из пар форма:

pattern { action }

Либо pattern, либо action (включая закрывающую скобку) символы) могут быть опущены.

Узоры

Шаблон - это любое допустимое выражение, диапазон которого определяется двумя выражениями, разделенными запятой, или одним из двух специальных шаблонов BEGIN или END.

Специальные узоры

Утилита awk распознает два специальных шаблона: BEGIN и END. Каждый шаблон BEGIN должен быть сопоставлен один раз, и его связанное действие выполняется перед прочтением первой записи ввода, за исключением, возможно, использования функции getline (см. Ввод / вывод и общие функции) в предыдущем BEGIN действии. и до назначения командной строки. Каждый шаблон END должен быть сопоставлен один раз, и соответствующее действие выполняется после прочтения последней записи ввода. Эти два шаблона должны иметь связанные действия.

BEGIN и END не должны сочетаться с другими шаблонами. Допускается использование нескольких шаблонов BEGIN и END. Действия, связанные с шаблонами BEGIN, должны выполняться в порядке, указанном в программе, как и действия END. Шаблон END может предшествовать шаблону BEGIN в программе.

источник: awk стандарт POSIX

Заявление

/foo/ || END { action }

, таким образом, не допускается, так как сочетает END с другим шаблоном.

См. Ответ Эд Мортона для элегантного решения.

0 голосов
/ 02 января 2019

вы можете попробовать этот обходной путь

awk '{Last=$0} END{ if( Last ~ /foo/) print "action if" }' YourFile

но это только для последней строки последнего файла

0 голосов
/ 02 января 2019

это может быть проще

$ awk '/foo/{exit} END{print "foo or END"}'

exit запустит блок END, поэтому вам не нужно повторять оператор.

0 голосов
/ 02 января 2019

Нет.Сделайте это вместо:

awk '
/foo/ { prtInfo() }
END   { prtInfo() }
function prtInfo() { print "foo or END" }
'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...