
Я получил странные комментарии, разместив awk
на SO ответ, в котором используется эта getline
функция.
Здесьэто ссылка на этот ответ.
После публикации моего ответа пользователь оставил следующий комментарий ( я его не критикую ) .
Не очень хорошее решение, оно будет объединять строки независимо от содержимого и не обрабатывать больше строк, если это необходимо. И вам следует избегать использования getline.
Там говорится, что нам следует избегать getline
функции в awk
. Поэтому мои вопросы таковы:
- Безопасно ли использовать
getline
функцию в awk? - В каких случаях следует использовать, а
getline
в каких — нет? - Если эта функция дает неожиданные результаты, почему бы нам не отправить отчет об ошибке?
решение1
Большинство людей спорят о getline
том,стиль кодированияземля.
Это чуждо обычной awk
обработке, когда код обрабатывает одну запись за раз.
getline
(когда не используется как getline var < "file"
или "cmd" | getline
) вытягивает следующую запись (возможно, из следующего файла) в середине оператора кода. Легко потерять тот факт, что он увеличивает NR, FNR, может изменить FILENAME.
Еще одна вещь, о которой не следует забывать при его использовании, — это проверка возвращаемого значения, поскольку оно вернет 0 при EOF или <0 в случае ошибки.
Так что это не getline
или if/while (getline) ...
, это:
if/while ((getline) > 0) { .... }
Или:
if/while ((getline < "file") > 0) {...}
Большинство случаев использования getline
можно изменить, используя подход, подобный конечному автомату.
Вместо:
/pattern/ {getline; print}
Что, вероятно, неверно и должно быть написано так:
/pattern/ && (getline) > 0 {print}
Вы бы сделали:
found_pattern {print; found_pattern=0}
/pattern/{found_pattern=1}
Также обратите внимание, как эти два варианта отличаются, еслишаблонсопоставляется в двух последовательных строках.
Теперь, пока вы это знаете, getline
все в порядке. Если вы хотите обрабатывать несколько файлов одновременно, то вам нужно getline
, но не забудьте проверить возвращаемое значение:
while ((getline a < "a") > 0 && (getline b < "b") > 0) {
....