
awk
이 기능을 사용하는 SO에 답변을 게시할 때 이상한 댓글을 받았습니다 getline
.
여기해당 답변에 대한 링크입니다.
내 답변을 게시한 후 한 사용자가 아래와 같은 댓글을 달았습니다.( 비난하는 것이 아닙니다. )
좋은 해결책은 아닙니다. 내용에 관계없이 줄을 연결하고 필요한 경우 더 많은 줄을 처리하지 않습니다. 그리고 getline 사용을 피해야 합니다.
getline
의 함수를 피해야 한다고 명시되어 있습니다 awk
. 그래서 내 질문은,
getline
awk에서 함수를 사용해도 안전한가요 ?- 어떤 상황에서 사용해야 하며,
getline
어떤 경우에는 사용하면 안 되나요? - 이 기능이 예상치 못한 결과를 낳는다면 버그 보고서를 제출하는 것이 어떨까요?
답변1
대부분의 사람들은 논쟁을 벌인다 getline
.코딩 스타일지면.
awk
코드가 한 번에 하나의 레코드를 처리하는 일반적인 처리와는 다릅니다 .
getline
getline var < "file"
( 또는 로 사용되지 않는 경우 "cmd" | getline
)는 코드 문의 중간에 다음 레코드(아마도 다음 파일에서)를 가져옵니다. NR, FNR이 증가하고 FILENAME이 변경될 수 있다는 사실을 놓치기 쉽습니다.
이를 사용할 때 잊지 말아야 할 또 다른 사항은 반환 값을 확인하는 것입니다. EOF에서는 0을 반환하고 오류에서는 <0을 반환하기 때문입니다.
getline
그래서 그것은 또는 가 아닙니다 if/while (getline) ...
. 그것은 다음과 같습니다:
if/while ((getline) > 0) { .... }
또는:
if/while ((getline < "file") > 0) {...}
대부분의 사용법은 getline
상태 머신과 같은 접근 방식을 사용하여 바꿀 수 있습니다.
대신에:
/pattern/ {getline; print}
아마도 잘못된 것이므로 다음과 같이 작성해야 합니다.
/pattern/ && (getline) > 0 {print}
당신은 할 것입니다 :
found_pattern {print; found_pattern=0}
/pattern/{found_pattern=1}
또한 두 가지가 어떻게 다른지 참고하세요.무늬연속된 두 줄에서 일치합니다.
이제 당신이 그것을 알고 있는 한 getline
괜찮습니다. 여러 파일을 동시에 처리하려면 가 필요 getline
하지만 반환 값을 확인하는 것을 잊지 마세요.
while ((getline a < "a") > 0 && (getline b < "b") > 0) {
....