【问题标题】:Delete a variable in awk在 awk 中删除一个变量
【发布时间】:2016-02-29 19:03:47
【问题描述】:

我想知道是否可以删除awk 中的变量。对于数组,你可以说delete a[2],数组a[] 的索引2 将被删除。但是,对于一个变量,我找不到方法。

我得到的最接近的是var=""var=0

但是,不存在的变量的默认值似乎是0False

$ awk 'BEGIN {if (b==0) print 5}'
5
$ awk 'BEGIN {if (!b) print 5}' 
5

所以我也想知道是否可以区分设置为0的变量和未设置的变量,因为它似乎没有:

$ awk 'BEGIN {a=0; if (a==b) print 5}'
5

【问题讨论】:

    标签: variables awk


    【解决方案1】:

    没有取消设置/删除变量的操作。变量再次变为未设置的唯一时间是在函数调用结束时,当它是一个未使用的函数参数被用作局部变量时:

    $ cat tst.awk
    function foo( arg ) {
        if ( (arg=="") && (arg==0) ) {
            print "arg is not set"
        }
        else {
            printf "before assignment: arg=<%s>\n",arg
        }
        arg = rand()
        printf "after assignment: arg=<%s>\n",arg
        print "----"
    }
    BEGIN {
        foo()
        foo()
    }
    
    $ awk -f tst.awk file
    arg is not set
    after assignment: arg=<0.237788>
    ----
    arg is not set
    after assignment: arg=<0.291066>
    ----
    

    因此,如果您想执行一些操作 A,然后取消设置变量 X,然后执行操作 B,您可以使用 X 作为局部变量将 A 和/或 B 封装在函数中。

    请注意,默认值是零或空,而不是零或假,因为它的类型是“数字字符串”。

    您通过将未设置的变量与 null 和零进行比较来测试它:

    $ awk 'BEGIN{ if ((x=="") && (x==0)) print "y" }'
    y
    $ awk 'BEGIN{ x=0; if ((x=="") && (x==0)) print "y" }'
    $ awk 'BEGIN{ x=""; if ((x=="") && (x==0)) print "y" }'
    

    如果您需要删除一个变量,那么您始终可以使用单元素数组:

    $ awk 'BEGIN{ if ((x[1]=="") && (x[1]==0)) print "y" }'
    y
    $ awk 'BEGIN{ x[1]=""; if ((x[1]=="") && (x[1]==0)) print "y" }'
    $ awk 'BEGIN{ x[1]=""; delete x; if ((x[1]=="") && (x[1]==0)) print "y" }'
    y
    

    但是恕我直言,这会混淆您的代码。

    取消设置变量的用例是什么? var=""var=0 不能用它做什么?

    【讨论】:

    • 当试图清空stack 变量时,一切都始于this answer。对我来说,对var="" 进行硬编码而不是直接删除它看起来有点奇怪。
    • 是的,我明白了,如果堆栈是作为数组实现的,您会删除该数组,但它是作为字符串实现的,那么为什么不能删除它呢?答案只是这不是你用任何语言初始化字符串的方式。当然,您始终可以将其实现为完全存储在stack[1] 中的字符串,然后愉快地删除stack,但这不会提高代码的可读性!
    • @EdMorton awk 'BEGIN {a=0; if (a==b &amp;&amp; length(b)&gt;0) print 5}' 可以吗?
    • @EdMorton 如果变量 b 未设置 .... 我的意思是 .... awk 'BEGIN {a=0; if (a==b &amp;&amp; length(a)==length(b)) print 5}' 换句话说
    • 漂亮!所以给You test for an unset variable by comparing it to both null and zero一个重要的评论。
    【解决方案2】:

    未设置的变量会扩展为 ""0,具体取决于对其进行评估的上下文。

    出于这个原因,我会说这是一个偏好问题,取决于变量的使用。

    鉴于我们在END 块中使用a + 0(或稍有争议的+a)将可能未设置的变量a 强制为数字类型,我猜你可能会争辩说自然的“空”值为""

    鉴于以下情况,我不确定您在问题中显示的案例是否有太多内容需要阅读:

    $ awk 'BEGIN { if (!"") print  }'
    5
    

    "" 是假的,这不足为奇)

    $ awk 'BEGIN { if (b == "") print 5 }'
    5
    

    (未设置变量的计算结果等于"",与0 相同)

    【讨论】:

    • 最后一点,不,它正在删除索引以及它在内存中指向的内容 - 在delete a[2] 之后尝试2 in a
    • @Ed 我猜想正确解释2 in a 的输出需要知道测试在做什么(我不知道!)
    • a 是一个哈希表,2 in a 正在访问您在哈希2 时到达的内存位置。如果已填充,则 2 in a 成功,否则不会。当您说delete a[2] 时,您正在释放散列2 指向的位置的内存。
    • 我接受了 Ed Morton 的回答,因为它给出了关键评论:“您通过将其与 null 和零进行比较来测试未设置的变量”。尽管如此,这也非常有用,您向我展示了我不知道的+a 的技巧。非常感谢!
    猜你喜欢
    • 2017-06-18
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 2011-12-07
    • 2018-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多