AWK에 레코드 계산에 문제가 있습니다.

AWK에 레코드 계산에 문제가 있습니다.

안녕하세요, 길이 문제가 있는 레코드 수를 계산하는 awk 표현식이 있습니다. 문제는 오류가 없을 때 내 카운트가 0이 아니라는 것입니다.

암호

err_count=$(
    awk -v m=1 -v p=5 -v count=0 '
        {
            c=substr($0,m,p)
            sub(" +$", "", c)
            if ( (length(c) > p) && (NR > 1) ) {
                printf "%s:%s:%s\n", FILENAME, FNR, $0 > "/dev/stderr"
                count++
            }
        }
        END {
            print count
        }
    ' /test/data/poc/BNC_fixedwidth.txt
)

입력 파일(고정 너비)

header
10027  20033t  [email protected]   19519  11/18/2021 12:06:10.260 PM BNC HardB 5 User Unk 125

error_count 변수는 항상 0 대신 공백을 제공합니다. 누구든지 불빛을 통해 볼 수 있다

답변1

코드가 실행된 후 이와 같은 작업을 수행 echo "$error_count"하지만 실제로 수행하려는 변수는 없습니다 echo "$err_count".

답변2

c의 너비가 지적하듯이, steeldriver그것은 결코 당신의 한계보다 길지 않을 것입니다:

c = substr($0, 1, 5)

길이는 c5보다 크지 않습니다.

그 이외의공백/ awk 스크립트에 구문 오류가 있기 때문에 비어 있습니다. 다음과 같은 작업을 수행하지 않는 한 이는 쉘에 인쇄되어야 합니다.2>/dev/null

최신 업데이트 이후에는 더 이상 작동하지 않습니다. 하지만 내가 아는 한, 당신은 그것을 바로잡지 않았습니다. 명확히 해야 할 것은 다음과 같습니다.

    if( (length(c) >  p  && NR > 1 )
#       ^
#       +--- Never closed.

게다가당신의 편집자그는 너무 많이 저주했습니다. \다음 줄에서 스크립트를 계속할 필요는 없습니다 . 그건:

  • { \하지만{

  • 아니요

     ... "/dev/stderr"\
        ++count
    
  • 하지만

       ... "/dev/stderr"
    ++count
    

명령문 끝에 세미콜론을 사용하는 것은 괜찮지만 코드를 더 읽기 쉽게 만들려면 세미콜론을 섞지 마십시오. ;어떤 이유로든 한 줄에 둘 이상의 명령문이 있는 경우를 제외하고는 모든 명령문의 끝에 사용하거나 사용하지 마십시오 . 그래서:

아니요:

    printf "%s: %d", $1, $2;
    ++foo
    ++bar;
    printf "%s: %d", $3, $4

하지만:

    printf "%s: %d", $1, $2
    ++foo
    ++bar
    printf "%s: %d", $3, $4

또는 (내가 아는 한 널리 사용되지 않음):

    printf "%s: %d", $1, $2;
    ++foo;
    ++bar;
    printf "%s: %d", $3, $4;

substr()$0를 이용 하고 가지치기하는 개념이기도 하다 sub().

awk의 기본 구분 기호는 <space>입니다. 이는 다른 문자 구분 기호와 다르게 처리됩니다. 즉, 여러 공백이 구분 기호로 연결됩니다. 따라서 두 줄 모두에 있습니다.

A B C
  A    B     C

다음으로 이어진다:

$1 == A
$2 == B
$3 == C

당면한 문제에 대해서는 다음과 같이 할 수 있습니다.

awk \
    -v width_max=5 \
    -v field_validate=1 \
'
BEGIN {
    err_count = 0
}
$1 == "header" {
    next
}
NF < field_validate || length($field_validate) > width_max {
    printf "%s:%d:%d:%s\n", FILENAME, NF, FNR, $0 > "/dev/stderr"
    ++err_count
}
END {
    printf "%d", err_count
}

' sample

NF수표를 별도의 수표로 받을 수도 있다는 점에 유의하시기 바랍니다 . 그것은 다음과 같습니다:

NF != field_count {
    # NF does not match with required fields
}

field_count정의된 변수는 어디에 있습니까?

FS, NF 등에 대한 간단한 예제 스크립트를 확인하실 수 있습니다.

awk -v field_count=3 \
'
NF != field_count {
    printf "NF mismatch %d != %d\n", NF, field_count
}
{
    printf "<%s><%s><%s>\n", $1, $2, $3
}
' <<EOF
AA BB CC
AA      BB    CC
   AA   BB      CC
AA BB
AA BB CC DD
EOF

관련 정보