AWK 在计算记录数时出现问题

AWK 在计算记录数时出现问题

你好,我有一个 awk 表达式,它计算有长度问题的记录数。问题是,当没有错误时,我的计数不为零

代码

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 总是给我空白而不是零。任何人都可以透过一些灯光

答案1

您在代码运行后正在执行echo "$error_count"或类似的操作,但您没有这样的变量,而实际上是打算这样做echo "$err_count"

答案2

正如 c 的宽度所指出的,steeldriver它永远不会长于您的限制:

c = substr($0, 1, 5)

的长度c永远不会> 5。

除此之外就是空白的/ 空,因为 awk 脚本中有语法错误。这应该打印到 shell 除非你做了类似的事情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()这也是使用of$0和修剪 that by 的概念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

相关内容