【问题标题】:AWK: Forcing/Casting Uninitialized Variable as type "array" rather than "numeric-string"AWK:将未初始化的变量强制/强制转换为“数组”类型而不是“数字字符串”
【发布时间】:2017-06-14 02:05:39
【问题描述】:

解决 AWK 递归难题。

我有一个递归任务,我必须填写一个数组。但是,我必须首先将数组作为参数传递。递归填充数组。为此,递归调用需要知道数组的长度,以便它们可以添加到数组的末尾。

唯一的问题是,在对参数运行函数后,我无法填充数组的第一个元素——length()isarray() 在未知参数上运行似乎都强制它为标量类型.

所以在我使用长度之前,我需要一些方法来知道我是否是第一次添加到数组中。我宁愿不传递一个额外的参数来记录递归的深度,并告诉代码数组何时为空或不符合逻辑。但我知道这种解决方法。


以下是该问题的最小可验证示例:


最小可验证示例:

#! /bin/awk -f
BEGIN{
    test(x)
}

function test(x,   y){
    y = length(x)
    x[1] = 1            # <- fatal: attempt to use scalar parameter as an array
}

同时,这有效:

#! /bin/awk -f
BEGIN{
    test(x)
}

function test(x,   y){
    #  y = length(x)
    x[1] = 1            # <- now it works
}

我需要做的是能够访问未初始化变量的长度(因为,在递归中,它通常会被初始化,但第一次,它不会)而不强制它是标量类型。我知道在数组中存储“长度”索引的解决方法。

如何在 awk 中完成此功能?

【问题讨论】:

    标签: arrays recursion awk


    【解决方案1】:

    听起来这就是你想要的:

    $ cat tst.awk
    BEGIN{
        test(x)
        print "done"
    }
    
    function test(x,   y,i){
        for (i in x) {
            ++y
        }
        x[y+1] = 1
    }
    
    $ awk -f tst.awk
    done
    

    通过在 x 上使用数组运算符 (in),我告诉 awk x 是一个数组,因此如果它之前从未输入过(您所说的未初始化),那么它将是在这一点上输入为数组。

    使用length() 对您没有帮助,因为它可以在字符串和数组上调用,并且默认情况下它的 arg 被假定为字符串,因此调用它是将x 作为字符串输入。使用 isarray() 只会将 x 识别为数组 AFTER x 被键入为一个数组,第一次通过它,就像 length() 一样,isarray(x) 将键入 x 作为一个字符串,因为它可以采用任一类型的 arg。

    【讨论】:

    • 有趣!即使在 x[y+1] 语句 length(x) 在函数体中失败之后;我猜有些怪癖。
    猜你喜欢
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    • 2019-03-25
    相关资源
    最近更新 更多