我正在尝试根据条件计算文件中列的空记录。但条件不行。
- 输入示例:固定宽度文件,
761128424607/22/20197611284246CAD052020DHH 0073578EKLAVY3
ELEKBAFXXL7900271761128424406/22/20197611284244CAD042020DKA 0038244EDITTU8
761128424606/22/20197611284246CAD052020DHH 0073578EKLAVY3
ELEKBAFXXL7900271761128424406/22/20197611284244CAD042020DKA 0038244EDITTU8
- 代码
RE='[[:space:]]{17}' awk -v m=1 -v p=17 -v r='&& substr($0,28,2)==06' $'BEGIN{re = ENVIRON["RE"]}{c = substr($0,m,p)} c ~ "^(" re ")$" r {N++} END {print N+0}' < input_file.txt
- 所需的输出:
1
,因为文件中有 2 条记录为空,并且这 1 条记录满足条件substr($0,28,2)==06
- 实际输出:
0
,这是错误的
答案1
这将通过让 shell 变量的内容在被调用来解释它r
之前扩展成为 awk 脚本的一部分来完成您所要求的操作,但几乎可以肯定有一种更好的方法来完成您真正想做的事情awk
:
$ r='&& substr($0,28,2)=="06"'
$ RE='[[:space:]]{17}' awk -v m=1 -v p=17 '
BEGIN { re = ENVIRON["RE"] }
{ c = substr($0,m,p) }
c ~ "^(" re ")$" '"$r"' { N++ }
END { print N+0 }
' file
1
如果你必须&& substr($0,28,2)=="06"
在某个地方写,那么你为什么不把它写在 awk 脚本中而不是 shell 变量中就一点也不明显了——无论你想做什么,都必须有更好的方法。
答案2
awk ... r='&& substr($0,28,2)==06'
'... c ~ "^(" re ")$" r { ... } '
这看起来像是您正在尝试使用 awk 变量来动态构建条件?也就是说,使用 awk 变量的内容r
作为 awk 语法的一部分。
我认为这行不通。在 awk 中,背对背值被视为字符串连接,因此会变成类似 的内容c ~ "^(" re ")$&& substr($0,28,2)==06"
,即它会将 的内容r
作为正则表达式的一部分进行匹配。
例如,awk -v var=bar '$0 ~ "foo" var'
将打印包含 的行foobar
,即使变量包含&&
等,它的工作原理也类似。
它可能也无法在任何其他编程语言中工作,因为代码和数据之间的分离几乎是理智和安全程序的要求。即使在 shell 中也不能这样工作。 (没有eval
或这样的。)
只需完整地写出整个表达式即可。
答案3
通过一些更改,您可以让它输出预期的结果:
RE='[^[:space:]]' awk -v m=1 -v p=17 \
$'(r=substr($0,28,2)=="06")&&
(substr($0,m,p) !~ re) {N++}
BEGIN {re = ENVIRON["RE"]}
END {print N+0}' < input_file.txt
编辑:-
- 将命令行上声明的 awk 变量 r 转换为
$'...'
代码块内。 - 删除
&&
,将其转换为布尔值。 - 坚持在和布尔条件
&&
之间。c ~ ...
r
- 将数字比较更改
==06
为字符串比较=="06"
答案4
使用 GNU awk
,您可以使用FIELDWIDTHS
变量来指定固定宽度字段的宽度:
gawk '($1!~/[^ ]/) && ($3=="06"){++c} END{print c+0}' FIELDWIDTHS='17 10 2 *' file
您可以尝试参数化 awk 脚本 – 一些尝试:
str=06 gawk -v FIELDWIDTHS='17 10 2 *' '
($1 !~ /[^ ]/) && ($3"" == ENVIRON["str"]) {
++c
}
END {print c+0}
' file
str=06 rexp='^ {17}$' gawk -v FIELDWIDTHS='17 10 2 *' -v rexp_col=1 -v str_col=3 '
($rexp_col ~ ENVIRON["rexp"]) && ($str_col"" == ENVIRON["str"]) {
++c
}
END {print c+0}
' file