代码之家  ›  专栏  ›  技术社区  ›  oliv

测试awk中不存在的变量

awk
  •  2
  • oliv  · 技术社区  · 8 年前

    我想测试一个可能存在或不存在的变量的值,我正在做:

    if(a<1) print "fail"
    

    这很好用。

    如果我重新测试同一个变量,如果这个变量没有设置在第一位, awk 将此变量视为已设置。

    $ awk 'BEGIN{if(a<1) print "fail"; if(a) print "fail"; }'
    fail
    

    在上面的语句中,我预计不会打印任何内容,因为变量 a 从未设置为任何内容。

    你能解释为什么会有这样的行为吗?

    如果这很重要的话,我正在使用 GNU Awk 4.2.1

    3 回复  |  直到 8 年前
        1
  •  5
  •   Ed Morton    8 年前

    背景:所有标量awk变量最终都是“numeric”或“string”类型。未初始化的变量属于另一种类型,称为“数字字符串”,因为它的最终类型未知,并且它的唯一值为零或null。看起来像数字的用户输入也是数字字符串类型,但显然有一个特定的值,而不是零或null。第一次使用变量时,awk根据使用该变量的上下文确定其最终类型(数字或字符串)。

    因此,在您的代码中,您有:

    if(a<1) print "fail"
    

    a 未设置,因此它的值为零或null,在与数字1比较的上下文中,无论您认为它是零还是null,两个可能的值都小于1,依此类推 "fail" 已打印。有一张图表 https://www.gnu.org/software/gawk/manual/gawk.html#Variable-Typing 这表明实际上正在使用数字比较,但在这种情况下,这并不重要。

    因此,您的代码未设置 一 在第一次按照您的想法进行测试之后。一个更有趣的测试可以更好地说明发生了什么:

    $ 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
    
        2
  •  2
  •   karakfa    8 年前

    未分配变量采用“false”值,即0或空字符串,具体取决于它们所引用的上下文。这可能会澄清。。。

    $ awk 'BEGIN{if(a==0)  print "a=0"; 
                 if(a=="") print "a=\"\""; 
                 if(!a)    print "a is false"}'
    

    印刷品

    a=0
    a=""
    a is false
    
        3
  •  0
  •   Micha Wiedenmann Lieven Keersmaekers    8 年前

    来自文档

    AWK变量是动态的;它们在第一次使用时就存在了。
    。。。
    未初始化的变量具有数值0和字符串值“”(null或空字符串)。

    在您的声明中:

    $ awk 'BEGIN{if(a<1) print "fail"; if(a) print "fail"; }'
    

    自从 a 初始化为 0 (或 "" ),则, if (a<1) 成功和 if (a) 失败。