我想测试一个可能存在或不存在的变量的值,我正在做:
if(a<1) print "fail"
Run Code Online (Sandbox Code Playgroud)
这很好用。
如果我然后重新测试相同的变量并且如果这个变量没有被设置,awk将会看到这个变量被设置。
$ awk 'BEGIN{if(a<1) print "fail"; if(a) print "fail"; }'
fail
Run Code Online (Sandbox Code Playgroud)
在上面的语句中,我希望不会打印任何内容,因为变量a从未设置为任何内容。
你有什么解释为什么会有这样的行为吗?
如果这很重要,我正在使用 GNU Awk 4.2.1
背景:所有标量 awk 变量最终都是“数字”或“字符串”类型。未初始化的变量是一种不同的类型,称为“数字字符串”,因为它的最终类型是未知的,并且它具有唯一的零值或空值。看起来像数字的用户输入也是数字字符串类型,但显然具有特定值,而不是零或空值。第一次使用变量时,awk 会根据使用该变量的上下文确定它的最终类型(数字或字符串)。
所以在你的代码中你有:
if(a<1) print "fail"
Run Code Online (Sandbox Code Playgroud)
a尚未设置,因此它的值为零或空,并且在与数字 1 进行比较的上下文中,无论您认为它为零还是空,两个可能的值都小于 1,因此"fail"被打印。https://www.gnu.org/software/gawk/manual/gawk.html#Variable-Typing上有一个图表,显示实际使用了数字比较,但在这种情况下无关紧要。
因此,您的代码a在第一次测试后并没有像您想象的那样设置。一个更有趣的测试可以更好地展示正在发生的事情:
$ awk 'BEGIN{if(a<1) print "is lt 1"; if(a=="") print "is null"; if (a==0) print "is 0" }'
is lt 1
is null
is 0
$ awk 'BEGIN{a=0; if(a<1) print "is lt 1"; if(a=="") print "is null"; if (a==0) print "is 0" }'
is lt 1
is 0
$ awk 'BEGIN{a=""; if(a<1) print "is lt 1"; if(a=="") print "is null"; if (a==0) print "is 0" }'
is lt 1
is null
Run Code Online (Sandbox Code Playgroud)