awk에서는 언제 BEGIN이 필요합니까?

awk에서는 언제 BEGIN이 필요합니까?

다음 명령은 동일한 대답을 생성합니다.

tail -n 1 ~/watchip.sh.csv | awk 'BEGIN { FS = "," } ; { print $1 }' 
tail -n 1 ~/watchip.sh.csv | awk '{ FS = "," } ; { print $1 }'

편집: 이 질문을 게시한 이후 위의 두 명령이 동일한 대답을 생성한다는 내 주장이 틀렸다는 것을 알게 되었습니다. 적어도 일반적으로는 그렇지 않습니다. 그래서 위의 명령은 BEGIN명령문이 필요한 경우의 예인 것 같습니다 . 혼란을 드려 죄송합니다.

저는 숙련된 awk사용자는 아니지만 이 제품을 사용하고 문서를 읽어 보다 나은 사용법을 얻으려고 노력하고 있습니다. 그러나 내가 BEGIN과 END에서 읽은 모든 내용은 모호합니다(나에게는 거의 이해가 되지 않습니다). 아마도 제가 awk매우 제한된 상황에서만 사용했기 때문일 수도 있습니다.

BEGIN 문이 언제인지 간단히 설명해 줄 수 있는 사람이 있습니까?필수의존재하다 awk?

답변1

BEGINand END절은 실제로 어떤 일을 수행하고 싶을 때 주로 사용됩니다.awk앞으로그리고뒤쪽에파일의 실제 처리는 별도로 발생합니다. 따라서 이 논리를 사용하면 해당 논리의 명령문/작업이 주어진 입력 파일에 대해 한 번만 실행됩니다.

일반적으로 어떤 유형의 작업이 수행됩니까 BEGIN?

  1. 줄 입력을 분할하는 데 사용되는 특수 변수(예: 입력 및 출력 필드 구분 기호)를 초기화합니다 FS. OFS항상 구문을 사용하여 이러한 특수 변수를 정의하거나 -v FS=정규식 연산자를 통해 정의 할 수 있지만 -F','그렇게 하면 훨씬 더 읽기 쉽습니다. 귀하의 예에서 판단하면 입력 파일의 각 줄에 대한 변수를 초기화하기 때문에 { FS="," }본문에서 이를 정의 해야 하는 것은 다소 중복됩니다. awk예를 들어 행에 n개의 행이 포함되어 있으면 초기화가 n번 발생합니다.

    echo "1,2,3" | awk 'BEGIN {FS=OFS=","} {print $1}'
    
  2. 스크립트 본문에서 생성된 출력에 대한 사용자 정의 헤더 행을 정의합니다 awk. 예를 들어 이전 예에서는 첫 번째 열 값을 인쇄하고 있음을 나타내는 헤더를 인쇄하고 싶었습니다.

    echo "1,2,3" | awk 'BEGIN {FS=OFS=","; print "First column values only"} {print $1}'
    
  3. (선택 사항 - 가독성을 위해) - 프로그램 본문 내에서 사용될 변수를 초기화할 수도 있습니다. 권장되지는 않지만 변수 초기화를 동적으로 처리하므로 변수의 상태를 이해하는 데 awk도움이 될 수 있습니다.BEGIN

    echo "1,2,3" | awk 'BEGIN {FS=OFS=","; counter = 0; } $1 == "1" { counter++ }'
    

일반적으로 어떤 유형의 작업이 수행됩니까 END?

  1. 명령 본문에서 처리된 행 수를 추적합니다 awk. 일반적인 관용어는 파일의 줄 수를 추적하는 것입니다. 우리는 각 줄이 처리될 때마다 증가하는 실행 카운터인 특수 awk변수를 사용합니다. NR즉, 첫 번째 행 변수 값은 1이 된 다음 증가합니다. 하지만 이 경우 파일의 총 줄 수를 어떻게 인쇄할 수 있습니까? print NR파일을 처리하는 동안 현재 줄 번호를 인쇄 하기 때문에 파일 본문에서는 이를 수행할 수 있는 방법이 없습니다 . awk예를 들어 아래의 첫 번째 스니펫은 작동하지 않습니다. 그래서 END이것은 그 안에 있는 진술이 다음과 같을 때 발생합니다.뒤쪽에파일 처리가 완료되었습니다. 따라서 같은 방식으로 인쇄하면 END저장된 마지막 값을 인쇄합니다.NR

    printf '1\n2\n\3' | awk '{print "total="NR}'
    total=1
    total=2
    total=3
    printf '1\n2\n\3' | awk 'END{print "total="NR}'
    total=3
    
  2. 헤더 정보를 인쇄하는 절 과 마찬가지로 BEGIN이 시점에서 모든 파일 처리가 완료되므로 문자열, 정보를 요약하여 인쇄할 수 있습니다.

이 문서효과적인 AWK 프로그래밍도구를 더 잘 이해하는 데 가장 좋은 리소스입니다.

답변2

"효과적인 AWK 프로그래밍"은 나에게 많은 도움이 되었습니다.

awk는 패턴과 작업으로 구성된 규칙과 함께 작동하며 둘 중 하나를 생략할 수 있지만 둘 다 생략할 수는 없습니다. BEGIN과 END는 패턴이고, {...}는 연산입니다. 패턴이 없거나 패턴 일치가 없으면 작업이 수행됩니다.

awk 'BEGIN      {FS=OFS=","}      {print $1}'
     ^pattern + ^action           ^ action without pattern

awk '{ FS = "," }         ;        { print $1 }'
     ^action without pattern       ^ another action without pattern

일반적인 awk 프로그램에서:

  • BEGIN{...}은 레코드보다 먼저 실행되므로 여기에서 필요한 모든 것을 초기화할 수 있습니다.
  • 각 레코드는 메인 루프인 패턴{...}을 실행합니다.
  • END{...}는 마지막 레코드 이후에 실행됩니다. 메인 루프가 완료되고 모든 데이터가 귀하의 손에 있으므로 원하는 것은 무엇이든 할 수 있습니다.

관련 정보