Почему awk выводит эту строку больше одного раза?

Почему awk выводит эту строку больше одного раза?

У меня есть следующий ldif:

dn: cn=Robert Smith,ou=people,dc=example,dc=com
objectclass: inetOrgPerson
cn: Robert Smith
cn: Robert J Smith
cn: bob  smith
sn: smith
uid: rjsmith
userpassword: rJsmitH
carlicense: HISCAR 123
homephone: 555-111-2222
mail: [email protected]
alias: [email protected]
alias: [email protected]
description: nice hair
ou: Human Resources

dn: cn=John Doe,ou=people,dc=example,dc=com
objectclass: inetOrgPerson
cn: John Doe
cn: John Walker Doe
cn: Johnny
sn: Doe
uid: jdoe
userpassword: topsecret
carlicense: AKAHH 123
homephone: 123-458-362
mail: [email protected]
alias: [email protected]
alias: [email protected]
description: cool guy
ou: Sales

Теперь я запускаю для него команду awk:

awk '/^mail:/ { mail = $2 }; {print mail };' ldif

Ожидаемый результат будет следующим:

[email protected]
[email protected]

Фактический результат:

[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

Я не совсем понимаю, почему awk выдает этот вывод несколько раз. Я был бы очень признателен, если бы кто-нибудь объяснил мне это, так как я новичок в awk и не особо им пользовался. Я уже проконсультировался с man-страницей и Google, но, похоже, я ищу там не то...

EDIT: Я понимаю, что awk обрабатывает текстовые потоки строками. Я думаю, что мой "print" просто печатает вывод так часто, как много строк в моем ldif-файле. Но как мне запретить awk делать это? Я хочу печатать каждый результат только один раз..

решение1

Условие /^mail:/не влияет на все последующие инструкции, а только на первую ( mail = $2).

В результате print mailвыполняется вторая инструкция ( )для каждой строки.

Вот почему в начале вывода есть несколько пустых строк ( mailпока не установлено).

Подойдет любой из этих вариантов:

awk '/^mail:/ { { mail=$2 }; {print mail } };' ldif

awk '/^mail:/ { mail=$2; print mail };' ldif

Лично я бы предпочел:

awk '/^mail:/ { print $2 }' ldif

решение2

@Dennis предложил решение, обеспечивающее правильный синтаксис, но не дал полного ответа на изначальный вопрос «Почему awk печатает эту строку более одного раза?»

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

if LINE starts with "mail:"
    set MAIL to value of second field of the input record
endif

print MAIL

Причина дублирования строк вывода заключается в том, что оператор печатиснаружиусловный оператор, и поэтому выполняется длякаждыйстрока ввода, а не просто строки, соответствующие регулярному выражению. Более того, поскольку переменная mailустанавливается только внутри условного оператора, старое значение используется снова и снова до тех пор, пока в следующий раз строка ввода не совпадет с условным оператором.

Связанный контент