Причина, по которой ваша программа выполняет дальнейшие действия после нажатия клавиши, заключается в том, что она ожидает ввода.Обычно входные данные поступают из файлов или выходных данных другой команды при использовании канала.Однако время от времени awk может ожидать ввода от /dev/stdin
.Это тот случай, когда вы вызываете вашу программу без каких-либо файлов в качестве аргумента (см. [1] раздел Расширенное описание: Общая структура программы ) или используете в качестве аргумента (см. [1] section Операнды ).
$ awk -f source.awk # input from /dev/stdin via keyboard
$ awk -f source.awk [file] - # input from /dev/stdin via [file and] keyboard
$ cmd | awk -f source.awk # input from /dev/stdin via pipe
$ cmd | awk -f source.awk [file] - # input from /dev/stdin via [file and] pipe
Имейте в виду, что приведенные выше случаи могут потребовать ввода от /dev/stdin
.Необходимость ввода зависит от структуры программы awk.Таким образом, мы можем теперь задать себе следующий вопрос:
Когда awk требует ввода из файла, команды, клавиатуры или любой другой возможной формы ввода?
A awkПрограмма состоит из пар вида:
pattern { action }
, где pattern
- это, как правило, логическое условие для определения, следует ли выполнять action
.Posix awk распознает два специальных шаблона: BEGIN
и END
.У Gnu awk есть и другие специальные шаблоны, такие как BEGINFILE
и ENDFILE
, но для этого ответа мы можем классифицировать их как регулярные.Теперь мы можем сделать следующие утверждения (см. [1] подраздел Специальные шаблоны ):
- Обычный шаблон всегда требует ввода.
- Специальный шаблон
BEGIN
не требует ввода (кроме случаев, когда он содержит getline
) - Специальный шаблон
END
всегда требует, чтобы ввод считывался перед его выполнением
Отсюда можно сказать:
Программе awk не требуется ввод если
- , он состоит только из
BEGIN
паттернов, которые не вызывают getline
. - или,
BEGIN
pattern вызывает exit
подпрограмму до того, как может быть вызван любой getline
.
в любом другом случае, awk потребует ввода!
Последнее утверждение происходит из правил, связанных с оператором exit
.Оператор exit
должен вызывать все действия END
в том порядке, в котором они происходят в исходном коде программы, а затем завершать программу без чтения дополнительных данных .(См. [1] подраздел Действия )
Исходя из вышеизложенного, теперь мы можем ответить на вопрос ОП:
Почемумой AWK-Script ждет, пока я нажму клавишу?
Поскольку программа OP выглядит примерно так:
BEGIN { something without exit }
pattern { something else }
END { something final }
, она потребует ввода.Кроме того, OP называет его как
$ awk -f file.awk
, что означает, что ввод поступает с /dev/stdin
или, в данном случае, с клавиатуры.Поэтому awk будет ждать выполнения обычной пары action-pattern, пока не получит запись (здесь строка) с клавиатуры.Т.е. нажмите несколько клавиш, а затем Enter .Каждый раз, когда такая строка отправляется, awk будет обрабатывать все обычные шаблоны.Шаблон END
будет выполняться только после завершения ввода.Вы можете сообщить awk, что ввод с клавиатуры завершен, отправив конец файла (EOF) через клавиатуру.Это делается нажатием Ctrl - D .
Чистая перезапись кода может быть найдена в ответе Ed Morton .Быстрый обходной путь в ответе Jotne .
[1]: стандарт Posix, раздел утилит, awk