在 awk 中删除一个变量

Posted

技术标签:

【中文标题】在 awk 中删除一个变量【英文标题】:Delete a variable in 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

【问题讨论】:

【参考方案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 的技巧。非常感谢!

以上是关于在 awk 中删除一个变量的主要内容,如果未能解决你的问题,请参考以下文章

将AWK结果分配给变量[重复]

如何在 AWK 中一次删除多个列和字段分隔符?

AWK - 从列表中删除最后一项

如何使用 shell(awk、sed 等)删除文件中的前两列

通过 grep/awk/cut 删除字符串中的多余点

sed 或 awk:删除模式后面的 n 行