новичок в awk, пытающийся понять мыслительный процесс awk

Связанный с этим вопрос здесь.

У меня есть два файла:

файл 1:

I am a cat  
I am a dog    
I am a dog  
I am a cat  
I am a dog

файл 2:

line 1
line 2

При выполнении:

awk '/cat/{getline <"file2"; print};1' file1
line 1
line 1
I am a dog
I am a dog
line 2
line 2
I am a dog

Я ожидаю:

line 1
I am a cat
I am a dog
I am a dog
line 2
I am a cat
I am a dog

Мое понимание awk в приведенном выше коде:

Прочитайте строку из файла 1, если cat существует, напечатайте строку из file 2, а 1 в конце указывает awk также напечатать строку из file 1. Если cat не найдено, awk ничего не печатает из file 2, но все равно напечатает соответствующую строку из file 1.

Похоже, что происходит то, что awk читает первую строку file 1, находит cat и печатает первую строку из file 2. Затем awk интерпретирует 1 как истинное для данного условия и снова печатает первую строку из file 2. Когда awk не находит cat, он интерпретирует 1 как истину и печатает из file 1?

Еще кое-что, что мне показалось интересным, это когда я запускаю это:

awk '/cat/{getline this<"file2"; print this};1' file1  
line 1
I am a cat
I am a dog
I am a dog
line 2
I am a cat
I am a dog

Что тут происходит? Спасибо за ваше время.


person thecomebackid    schedule 28.07.2016    source источник
comment
Надеюсь, это академический вопрос, и вы не собираетесь использовать какой-либо из сценариев в своем вопросе. Если есть, см. awk.freeshell.org/AllAboutGetline.   -  person Ed Morton    schedule 29.07.2016
comment
Спасибо за информацию @Эд Мортон. На самом деле не использую это ни для чего, просто учусь.   -  person thecomebackid    schedule 01.08.2016


Ответы (1)


awk '/cat/{getline <"file2"; print};1' file1
line 1
line 1
I am a dog
I am a dog
line 2
line 2
I am a dog

Когда строка I am a cat обрабатывается, она соответствует /cat/. Итак, действие выполнено. Действие считывает запись из file2, которая заменяет текущую $0 на line 1. Затем срабатывает второе правило, состоящее из 1. 1 — это выражение, которое всегда истинно, поэтому оно соответствует любой записи. У него нет действия, поэтому действие по умолчанию — печать. Таким образом, текущая запись печатается, и вы снова видите line 1.

Второе вхождение cat приводит к печати line 2. Синтаксис getline сохраняет связанный с ним открытый поток, так что несколько вычислений одного и того же выражения getline считывают последовательные строки. line 2 печатается дважды по той же причине, что и выше.

Во втором примере вы используете вариант синтаксиса getline, который считывается в указанное имя переменной. Таким образом, он не заменяет текущую запись. Когда оценивается правило 1, текущая запись по-прежнему I am a cat, поэтому печатается именно она, а не line 1 или line 2.

person Kaz    schedule 28.07.2016