Uma string pode ser usada como índice no array de arrays no gawk?

1

Vamos ver este arquivo:

9=foo 3=bar 84=baz 30=bin 71=bon
9=goo 3=gar 84=gaz 30=gin 71=gon
9=soo 3=sar 84=saz 30=sin 71=son

Executando esta linha do Gawk:

gawk '
{
    split($0,arr)
    for(i=1;i<=length(arr);i++){
        eq=index(arr[i],"=")
        num=substr(arr[i],eq+1)
        val=substr(arr[i],0,eq-1)
        printf "%s=%s ", num,val
        arr2[i][num] = val
    }
    printf ORS
}
END{
    print "---\n",arr2[2][9]}
' newfile.txt

O que eu espero obter é goo porque o primeiro índice da matriz é a segunda linha, e o segundo índice é o número antes do sinal = .

exemplos:

arr2[1][3] = bar
arr2[1][71] = bon
arr[3][30] = sin

assim por diante ..

Alguém pode me dizer por que não está funcionando e se é possível?

versão gawk GNU Awk 4.1.1, API: 1.1

Obrigado.

    
por Moshe 07.03.2017 / 11:52

1 resposta

0

Sim, é possível. O problema em seu roteiro, no entanto, é que você não está fazendo o que você acha que está fazendo. Primeiro de tudo, você está usando i como o índice da matriz de primeiro nível:

arr2[i][num] = val

Isso significa que i será um número de 1 ao comprimento da matriz e que arr2[i] será sobrescrito se alguma de suas linhas tiver o mesmo valor de sequência no mesmo campo.

Agora, a razão pela qual você está obtendo uma linha em branco como resultado (eu suponho que você está recebendo, você não disse) é que você está usando a ordem errada em sua matriz. Você tem:

arr2[i][num] = val

Então, por exemplo:

arr2[1][soo]=9

O que você parece estar esperando é o contrário:

arr2[1][9]=soo

Então, o que você precisa é:

arr2[i][value]=num

Se também alterarmos a definição da matriz para usar NR como um índice principal em vez de num para evitar colisões, obteremos:

gawk '
{
    split($0,arr)
    for(i=1;i<=length(arr);i++){
        eq=index(arr[i],"=")
        num=substr(arr[i],eq+1)
        val=substr(arr[i],0,eq-1)
        arr2[NR][val] = num
    }
}
END{
  for(i in arr2){
    for (num in arr2[i]){
      printf "arr2[%s][%s]=%s\n", i, num, arr2[i][num]
    }
  }
}
' newfile.txt
arr2[1][3]=bar
arr2[1][9]=foo
arr2[1][30]=bin
arr2[1][71]=bon
arr2[1][84]=baz
arr2[2][3]=gar
arr2[2][9]=goo
arr2[2][30]=gin
arr2[2][71]=gon
arr2[2][84]=gaz
arr2[3][3]=sar
arr2[3][9]=soo
arr2[3][30]=sin
arr2[3][71]=son
arr2[3][84]=saz

Como você pode ver, arr2[2][9] agora é goo conforme o esperado. A coisa toda é um pouco complexa demais. Você poderia simplificá-lo para:

$ awk -F'[ =]' '{
                    for(i=1;i<=NF;i+=2){
                        arr2[NR][$(i)]=$(i+1);
                    }
                } END{print  arr2[2][9]}' newfile.txt 
goo
    
por 07.03.2017 / 13:20

Tags