안녕하세요, 길이 문제가 있는 레코드 수를 계산하는 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)
길이는 c
5보다 크지 않습니다.
그 이외의공백/ 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