awk 명령에서 getline을 사용해도 안전합니까?

awk 명령에서 getline을 사용해도 안전합니까?

awk이 기능을 사용하여 SO에 답변을 게시했을 때 이상한 댓글을 받았습니다 getline. 여기해당 답변에 대한 링크입니다.

내 답변을 게시한 후 한 사용자가 다음과 같은 댓글을 달았습니다. ( 비난하는 것이 아닙니다. )

이는 좋은 솔루션이 아닙니다. 내용에 관계없이 행을 연결하고 필요할 때 더 많은 행을 처리하지 않습니다. 그리고 getline 사용을 피해야 합니다.

getline에서 함수를 사용 하지 말아야 함을 지적합니다 awk. 그래서 내 질문은,

  • getlineawk에서 함수를 사용해도 안전한가요?
  • 어떤 상황에서 사용해야 하고, getline어떤 상황에서 사용하면 안 되나요?
  • 이 기능이 예상치 못한 결과를 낳는다면 버그 보고서를 제출하는 것이 어떨까요?

답변1

대부분의 사람들은 getline이렇게 주장한다.코딩 스타일지면.

이는 awk코드가 한 번에 하나의 레코드를 처리하는 일반적인 처리와 다릅니다.

getlinegetline 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) {
  ....

관련 정보