在 Mawk 中行走多维数组

mgj*_*gjk 3 awk mawk

我能够在 gawk 中正确执行此操作,但是当我尝试将我的代码发布到它将运行的机器时,我意识到它正在使用 mawk ...

$ cat multidim.gawk
# test of multidimensional arrays
// {
        A[1][1]="A11"
        A[1][2]="A12"
        A[2][1]="A21"
        A[2][2]="A22"

        i=2
        for ( j in A[i] )
        {
                print "i=" i " j=" j " A[i][j]=" A[i][j]
        }
}


$ echo hi | awk -f multidim.gawk
i=2 j=1 A[i][j]=A21
i=2 j=2 A[i][j]=A22
Run Code Online (Sandbox Code Playgroud)

似乎 mawk 对多维数组的工作方式有不同的看法。当我使用 mawk 在 Debian 上运行它时,出现语法错误。A[i,j] 似乎是正确的语法,它“合成”了多维数组。

所以我尝试了两件事,都不起作用:

$ cat multidim.mawk
// {
        A[1,1]="A11"
        A[1,2]="A12"
        A[2,1]="A21"
        A[2,2]="A22"

        i=2
        for ( j in A[i] )
        {
                print "i=" i " j=" j "a[i,j]=" a[i,j]
        }
}

$ echo hi | awk -f multidim.mawk 
awk: multidim.mawk: line 9: syntax error at or near [
Run Code Online (Sandbox Code Playgroud)

似乎很明智,在“多维”数组上使用 1dim 数组索引会产生错误。

试图只遍历整个数组,以便我可以使用 if 语句来选择第一个维度甚至(非常低效和可怕)......但我什至不能这样做!:

$ cat multidim2.mawk
# test of multidimensional arrays
// { 
    A[1,1]="A11"    
    A[1,2]="A12"    
    A[2,1]="A21"    
    A[2,2]="A22"    

    for ( (i, j) in A )
    {
        print "i=" i " j=" j "a[i,j]=" a[i,j]
    }
}
$ echo hi | awk -f multidim2.mawk 
awk: multidim2.mawk: line 8: syntax error at or near )
Run Code Online (Sandbox Code Playgroud)

有没有办法在 mawk 中遍历多维数组?

除了 mawk 联机帮助页之外,还有其他语言参考吗?

谢谢!

mr.*_*tic 5

mawk(和nawk) 只提供合成的多维数组

gawk提供(自 4.0 起,thx manatwork)真正的多维数组,尽管手册页(恕我直言)误导了一点:在引入if ((i,j) in array)它之后紧随其后的是“ in 构造也可以在 for 循环中用于迭代所有元素一个数组。(自 v4.1.1 以来已修复!)。

但是,for ((i,j) in array)不是迭代这些的gawk方法,方法是(如您最初使用的那样):

 for (i in array)
     for (j in array[i])
         print array[i][j]
Run Code Online (Sandbox Code Playgroud)

随着nawk/mawk你被合成多维数组卡住了,所以

for (ij in A) {
    split(ij,xx,SUBSEP);
    printf("A[%s,%s]=%s\n",xx[1],xx[2],A[ij])
}
Run Code Online (Sandbox Code Playgroud)

现在,您的下一个问题将是ordering,数组索引是隐式字符串类型,而数组是隐式无序的。除非您对索引有单独的了解,否则就是具有从 0..N 开始的连续整数索引的简单非稀疏数组的情况。gawk提供了有序的解决方案in

如果您知道合成数组的索引,那么您可以使用A[i,j](被视为A[i SUBSEP j])或for/in和一些字符串拆分来重建iand的列表j,或if ((i,j) in A)(测试是否存在,没有索引的自动激活)。

gawk你不能使用(i,j) in arrwhere arr 是一个真正的多维数组时,你需要将它分解成两个(或多维)for循环,如上所述。不过,要完全正确,内部循环应该包含一个isarray()条件,因为不需要每个元素arr[i]依次是一个数组,gawk 也很乐意允许标量。

我不知道mawk除了手册页之外没有特定的文档,它旨在成为标准的新awk(即nawk)实现(因此没有真正的多维数组,没有索引排序,也没有isarray())。