O índice de array excluído reaparece no awk depois de usá-lo na expressão

1

Eu encontrei um comportamento estranho no awk . Eu queria excluir um elemento de matriz, mas descobri que esse elemento (apenas um índice, sem um valor) aparece novamente, se eu o usei em algum lugar no código após a exclusão. Esse comportamento é esperado?

awk '
# This function just for clarity and convenience.
function check(item) {
    if(item in arr) 
        printf "the array index \"%s\" exists\n\n", item 
    else 
        printf "the array index \"%s\" does not exist\n\n", item 
}

END {
    # Create element of array with index "f"
    arr["f"] = "yes"

    printf "The value of arr[\"f\"] before deleting = \"%s\"\n", arr["f"]

    # The first checking of the array - the index exists
    check("f")

    # Then delete this element
    # I am expecting no this element in the "arr" now
    delete arr["f"]

    # The second checking of the array - the index does not exist
    # as I were expecting
    check("f")

    # Use the non-existent index in expression
    printf "The value of arr[\"f\"] after deleting = \"%s\"\n", arr["f"]

    # The third checking of the array - the index exists again
    check("f")
}' input.txt

Resultado

The value of arr["f"] before deleting = "yes"
the array index "f" exists

the array index "f" does not exist

The value of arr["f"] after deleting = ""
the array index "f" exists
    
por MiniMax 09.03.2018 / 22:05

2 respostas

2

Esse é o comportamento esperado. Referenciar o valor de uma variável irá criá-lo se ainda não existir. Caso contrário, o seguinte seria um erro de sintaxe:

$ awk 'BEGIN { print "Foo is " foo[0]; foo[0]="bar"; print "Foo is " foo[0]; delete foo[0]; print "Foo is " foo[0] }'
Foo is
Foo is bar
Foo is

Isso é verdade mesmo para variáveis não-arrayed, mas como não há delete operator (algumas vezes) para variáveis planas, isso não acontece frequentemente sem arrays sendo envolvidos na questão.

    
por 09.03.2018 / 22:16
2

O comportamento que você encontra é porque essa linha recria silenciosamente o item da matriz que você excluiu antes:

printf "The value of arr[\"f\"] after deleting = \"%s\"\n", arr["f"]

Veja este pequeno teste:

$ awk 'BEGIN{a[1];delete a[1];for (i in a) print i}'
# nothing is printed
$ awk 'BEGIN{a[1];delete a[1];a[1];for (i in a) print i}'
1
$ awk 'BEGIN{a[1];delete a[1];print "a[1]=",a[1];for (i in a) print "key found:",i}'
a[1]= 
key found: 1
    
por 09.03.2018 / 22:12

Tags