AWK 함수를 사용하여 예제를 작성했지만 getline
혼란스럽습니다.
$ cat in
foo
bar
baz
$ awk '{ getline tmp; print tmp; print $0 }' in
bar
foo
bar
baz
출력의 처음 두 줄에서 확인된 대로 tmp
which will notchange 라는 변수로 다음 줄을 읽고 있습니다 .$0
bar
foo
이는 아래 표를 통해 확인됩니다AWK 프로그래밍 언어페이지 62:
나도 알고 있고 NR
내장 FNR
함수는 지금까지 읽은 행 수를 나타냅니다. 이것이 무슨 일이 일어나고 있는지 이해하는 데 핵심이라고 생각하지만 NR
한 패스의 변경이 향후 패스에 어떤 영향을 미치는지 혼란스럽습니다.
다음 두 줄은 다음과 같습니다.
baz
bar
두 번째 패스 $0 == bar
에서는 tmp == baz
.
그러면 다음 두 줄은 실제로는 한 줄일 것으로 예상됩니다.
baz
왜냐하면 세 번째 $0 == baz
와 tmp == null
.
그래서 내 예상 결과는 다음과 같습니다.
bar
foo
baz
bar
baz
나는 awk의 while 루프의 변화를 이해하는 것이 NR
이 출력을 이해하는 열쇠라고 생각합니다.
- 내 예상 출력이 잘못된 이유를 설명해 주실 수 있나요?그리고실제 출력이 올바른 이유는 무엇입니까?
나는 awk version 20070501
달리고 있다macOS 10.12.1
답변1
내 생각에 당신이 놓친 것은 NR
실제로 설정 getline
에서소비하다철사. 따라서 두 번째 호출에서는 bar
is가 사라졌으며 $0
is는 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 코드를 작성하는 매우 일반적인 방법입니다.
여기서 무슨 일이 일어나고 있는지 명확해야 합니다.
$0
1행부터 1행 까지 읽기getline
tmp
2행부터 2행 까지 읽기getline
tmp
그런 다음 print$0
, 즉 라인 2를 인쇄한 다음 라인 1을 인쇄합니다.- 다음 줄 쌍에 대해 반복합니다. 4번 줄이 인쇄되고 3번 줄이 인쇄됩니다.
홀수 줄의 경우 마지막 줄이 통과했다 getline $0
가 getline tmp
실패하는데 반환 상태를 확인하지 않아서 tmp
그대로 유지되고 끝에서 두 번째 줄을 다시 인쇄하게 됩니다.