AWK END 동작이 매뉴얼 페이지의 $0에 마지막 줄을 로드합니까?

AWK END 동작이 매뉴얼 페이지의 $0에 마지막 줄을 로드합니까?

나는 읽었다또 다른 대답사용 방법을 설명합니다.AWK출력의 마지막 줄을 확인하십시오.

$ seq 42 | awk 'END { print }'
42

따라서 END블록이 실행될 때 마지막 행이 $0.

첫 번째 줄이 BEGIN블록에 로드되지 않았기 때문에 이는 나를 놀라게 했습니다.

$ seq 42 | awk 'BEGIN { print }'
#=> blank
  • 이 동작이 어디에도 문서화되어 있나요? (검색해보니매뉴얼 페이지하지만 아무것도 찾지 못했습니다)

답변1

BEGIN블록은 입력이 처리되기 전에 실행되므로 $0아직 초기화되지 않았습니다.

블록 END은 아무 작업도 수행하지 않으며 $0마지막 값을 유지합니다. AWK 스크립트에서는 AWK가 모든 입력을 한 줄씩 읽고 일반적인 필드 분할 처리(할당 $0등)를 수행하지만 일치하는 블록을 찾지 않기 때문에 이것은 읽은 마지막 줄일 뿐입니다.

seq 42 | awk '{ $0 = "21" } END { print }'

END42가 아닌 21을 출력하므로 " 블록이 실행되는 동안 마지막 행을 로드 " 하는 경우가 아닙니다 $0.

이것은 문서화되어 있지 않습니다.gawk(1)맨페이지이지만 다음 문서에 문서화되어 있습니다.mawk(1)(분명히 AWK 구현의 경우):

마찬가지로 작업 시작 시 END, $0및 필드 의 값은 NF마지막 레코드에서 변경되지 않은 상태로 유지됩니다.

GNU AWK 매뉴얼은 다음과 같습니다.이 행동을 언급하다:

실제로 모든 BWK awk, mawk, 및 값은 규칙에 사용하도록 gawk예약되어 있습니다 .$0END

“BWK ”는 awkBrian Kernighan awk의 작품입니다."진짜 awk"FIXES; 문서에 명시된 대로 2005년에 이 동작을 구현했습니다 .

2005년 4월 24일: posix의 요구에 따라 END 블록에 et al의 값을 유지 lib.c하도록 수정되었습니다. $0보고서와 코드를 제공해 주신 havard eidnes에게 감사드립니다.

이 변화는 다음에서 볼 수 있습니다."진정한 awk" 역사. 최신 버전의 BWK는 awkGNU AWK와 동일한 방식으로 작동합니다.

$ echo three fields here | ./awk '{ $0 = "one" } END { print $0 " " NF }'
one 1
$ echo three fields here | ./awk 'END { $0 = "one"; print $0 " " NF }'
one 1

답변2

~에 따르면GNU awk 매뉴얼$0, END 규칙에 무엇이 포함되어야 하는지가 약간 불분명합니다 . POSIX 요구 사항NF "[그것의] 가치는 보존되어야 합니다"(*) , 그러나 언급되지 않았습니다 $0.

$0대부분의 경우 감독으로 인해 논리적으로 유지되어야 한다고 생각하더라도 표준에서는 유지된다고 말하지 않습니다 . 실제로 모든 BWK awk, mawk 및 gawk는 규칙에 사용할 $0값 을 유지합니다. END그러나 일부 다른 구현과 Unix awk의 많은 이전 버전에서는 이를 지원하지 않습니다.

어떤 의미에서는 이러한 행동이 논리적이라고 생각합니다. 필요한 경우 마지막 기록에 쉽게 접근할 수 있도록 블록을 $0종료 하세요. END첫 번째 레코드는 쉽게 액세스할 수 있으므로 NR == 1 {...}특별한 키워드가 필요하지 않습니다. 반면, BEGIN첫 번째 레코드를 로드하기 전에 블록을 실행하면 첫 번째 레코드에 맞춰 블록을 설정 FS하거나 RS활성화할 수 있습니다.

(*그 의미가 무엇인지는 댓글을 참조하세요.)

관련 정보