Andando em matrizes multidimensionais em Mawk

3

Eu sou capaz de fazer isso apropriadamente no gawk, mas quando tentei postar meu código na máquina onde ele irá rodar, percebi que estava usando o 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

parece que o mawk tem uma ideia diferente sobre como os arrays multidimensionais devem funcionar. Quando eu o executo no Debian com o mawk, recebo um erro de sintaxe. A [i, j] parece a sintaxe correta e "sintetiza" matrizes multidimensionais.

Então eu tentei duas coisas, nem trabalho:

$ 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 [

Parece sensato, usando um índice de matriz 1dim em um array "multidimensional" gera um erro.

Tentando apenas andar no array TODO, para que eu possa usar uma declaração if para selecionar a primeira dimensão (extremamente ineficiente e horrível) ... mas eu não posso nem fazer isso!

$ 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 )

Existe alguma maneira de percorrer um array multidimensional no mawk?

Existe uma referência de idioma diferente da página man falsa?

Obrigado!

    
por mgjk 15.10.2013 / 11:25

1 resposta

5

mawk (e nawk ) fornecem apenas arrays multidimensionais sintetizados .

gawk fornece (desde 4.0, thx manatwork ) matrizes multidimensionais verdadeiras, embora a página de manual (IMHO) desvie um pouco: imediatamente após a introdução de if ((i,j) in array) , segue com " A construção in também pode ser usada em um loop for para iterar todos os elementos de uma matriz. " (corrigido desde a v4.1.1!).

Mas, for ((i,j) in array) não é o caminho para iterar sobre estes, o gawk way é (como você usou originalmente):

 for (i in array)
     for (j in array[i])
         print array[i][j]

Com nawk / mawk você está preso a matrizes multidimensionais sintetizadas ,

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

Agora, seu próximo problema será ordenar , os índices de matriz são implicitamente do tipo string e os arrays são implicitamente desordenados. A menos que você tenha um conhecimento separado dos índices, como seria o caso de uma matriz simples não esparsa com índices inteiros consecutivos de 0..N. gawk oferece uma solução para um in ordenado .

Se você conhece os índices de um array sintetizado, pode usar A[i,j] (que é tratado como A[i SUBSEP j] ) ou for / in e alguma divisão de strings para reconstruir a lista de i e j , ou if ((i,j) in A) (teste de presença, sem autovivificação de índices).

Em gawk você não pode usar (i,j) in arr onde arr é um verdadeiro array multidimensional, você precisa dividi-lo em duas (ou quantas dimensões) for loops como acima. Para estar completamente correto, porém, o (s) laço (s) interno (s) deve conter uma condição isarray() , já que não é necessário que cada elemento de arr[i] seja um array, o gawk está feliz em permitir escalares também.

Não conheço nenhuma documentação específica de mawk além da página de manual , que pretende ser uma nova implementação padrão de awk (ou seja, nawk ) (portanto, não há matrizes multidimensionais verdadeiras, nenhuma classificação de índice e nenhum isarray() ).

    
por 15.10.2013 / 12:21

Tags