AWK에서 "getline"은 어떻게 작동하나요?

AWK에서 "getline"은 어떻게 작동하나요?

AWK 함수를 사용하여 예제를 작성했지만 getline혼란스럽습니다.

$ cat in
foo
bar
baz
$ awk '{ getline tmp; print tmp; print $0 }' in
bar
foo
bar
baz

출력의 처음 두 줄에서 확인된 대로 tmpwhich will notchange 라는 변수로 다음 줄을 읽고 있습니다 .$0

bar
foo

이는 아래 표를 통해 확인됩니다AWK 프로그래밍 언어페이지 62:

여기에 이미지 설명을 입력하세요.

나도 알고 있고 NR내장 FNR함수는 지금까지 읽은 행 수를 나타냅니다. 이것이 무슨 일이 일어나고 있는지 이해하는 데 핵심이라고 생각하지만 NR한 패스의 변경이 향후 패스에 어떤 영향을 미치는지 혼란스럽습니다.

다음 두 줄은 다음과 같습니다.

baz
bar

두 번째 패스 $0 == bar에서는 tmp == baz.

그러면 다음 두 줄은 실제로는 한 줄일 것으로 예상됩니다.

baz

왜냐하면 세 번째 $0 == baztmp == null.

그래서 내 예상 결과는 다음과 같습니다.

bar
foo
baz
bar
baz

나는 awk의 while 루프의 변화를 이해하는 것이 NR이 출력을 이해하는 열쇠라고 생각합니다.

  • 내 예상 출력이 잘못된 이유를 설명해 주실 수 있나요?그리고실제 출력이 올바른 이유는 무엇입니까?

나는 awk version 20070501달리고 있다macOS 10.12.1

답변1

내 생각에 당신이 놓친 것은 NR실제로 설정 getline에서소비하다철사. 따라서 두 번째 호출에서는 baris가 사라졌으며 $0is는 baz다른 getline행을 읽으려고 시도했지만 실패하고 is의 값은 tmp동일하게 유지됩니다(즉, bar).

반환 값을 확인하면 이해하기 더 쉬울 수 있습니다 getline.

awk '{ if ((getline tmp) > 0) print tmp; print $0 }' in
bar
foo
baz

답변2

더 큰 그림을 보면 명확해진다고만 말하면 충분합니다. awk 프로그램은 한 줄을 읽은 다음 해당 줄에서 프로그램을 실행하는 프로그램 텍스트 주위의 루프입니다. 프로그램 내에서 한 줄을 읽으면 주변 루프에서 해당 줄을 볼 수 없습니다. 해당 줄은 이미 사용되었습니다.

예를 들어, 프로그램

{ getline tmp; print tmp; print $0 }

다음과 같이 쓸 수 있다

BEGIN {
    while (getline $0) {
        getline tmp; print tmp; print $0
    }
}

BEGIN블록은 프로그램 시작 시 프로그램이 다른 작업을 수행하지 않을 때 한 번 실행됩니다. 확실히 이는 awk 코드를 작성하는 매우 일반적인 방법입니다.

여기서 무슨 일이 일어나고 있는지 명확해야 합니다.

  • $01행부터 1행 까지 읽기getline
  • tmp2행부터 2행 까지 읽기getline
  • tmp그런 다음 print $0, 즉 라인 2를 인쇄한 다음 라인 1을 인쇄합니다.
  • 다음 줄 쌍에 대해 반복합니다. 4번 줄이 인쇄되고 3번 줄이 인쇄됩니다.

홀수 줄의 경우 마지막 줄이 통과했다 getline $0getline tmp실패하는데 반환 상태를 확인하지 않아서 tmp그대로 유지되고 끝에서 두 번째 줄을 다시 인쇄하게 됩니다.

관련 정보