你好,我有一个 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