Como as matrizes associativas funcionam?

1
bash-3.00# cat iplogs.txt
180607 093423   123.12.23.122  133
180607 121234   125.25.45.221  153
190607 084849   202.178.23.4   44
190607 084859   164.78.22.64   12
200607 012312   202.188.3.2    13
210607 084849   202.178.23.4   34
210607 121435   202.178.23.4   32
210607 132423   202.188.3.2    167

bash-3.00# awk '{ip[$3]++;} END{for (var in ip)\
print var, "access", ip[var]," times"}' iplogs.txt
202.188.3.2 access 2  times
164.78.22.64 access 1  times
202.178.23.4 access 3  times
125.25.45.221 access 1  times
123.12.23.122 access 1  time

A saída acima não está clara para mim. Como $3 é incrementado para cada repetição valor?

Eu esperava que os valores atribuídos à matriz ip fossem como:

ip[123.12.23.122]=0
ip[125.25.45.221]=1

e assim por diante.

Então, tentei isso, mas o valor da matriz ip[var] não foi impresso.

bash-3.00# awk '{ip[$3]++;} END{for (var=0;var <= NR; var++)\
print var, ip[var]}' iplogs.txt
0
1
2
3
4
5
6
7
8
    
por munish 27.11.2012 / 16:41

1 resposta

3

Matrizes associativas usam strings como chaves, não índices inteiros. * A chave neste caso é $3 , que é uma variável de campo awk correspondente ao terceiro (3o) campo. Em sua entrada de amostra, essa seria a terceira coluna que contém sequências que se parecem com endereços IPv4. Na expressão ip[$3]++ , se $3 for "202.188.3.2" , então ip["202.188.3.2"] será incrementado. Como $3 é "202.188.3.2" um total de duas vezes em sua entrada de amostra, ip["202.188.3.2"] é incrementado duas vezes. Desde que começou em 0 no começo, como todas as variáveis awk não inicializadas, ele acaba com um valor de 2 .

Seu primeiro exemplo usa for (var in ip) . Essa é a maneira correta de iterar em uma matriz com chaves desconhecidas. Seu segundo exemplo usa for (var = 0; var <= NR; var++) . No entanto, como eu disse acima, ip foi criado como um array associativo cujas chaves são strings que se parecem com endereços IPv4 , não índices inteiros. Os elementos ip[0] , ip[1] , ... não existem porque nunca foram atribuídos (porque em nenhum momento $3 ever 0 , 1 , 2 ...), que é porque você obtém saída vazia ( "" ).

* Em awk , índices inteiros de array são convertidos em strings, então a[1] e a["1"] são o mesmo elemento.

    
por 27.11.2012 / 16:52

Tags