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를 처음 접하고 이전에 많이 사용해 본 적이 없기 때문에 누군가 나에게 설명해 주시면 매우 감사하겠습니다. 이미 매뉴얼 페이지와 구글을 참고했는데, 거기에서 잘못된 것을 찾고 있는 것 같아요...

편집: awk가 텍스트 스트림을 한 줄로 처리한다는 것을 이해합니다. 내 "인쇄"는 단순히 내 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

출력 라인이 중복되는 이유는 print 문이 다음과 같기 때문입니다.밖의조건문은 다음과 같이 실행됩니다.모든정규식과 일치하는 줄이 아니라 입력 줄입니다. 또한 mail변수는 조건문 내에서만 설정되므로 다음 입력 행이 조건문과 일치할 때까지 이전 값이 계속해서 재사용됩니다.

관련 정보