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
따라서 or 는 아니지만 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) {
....