Bash: espaço como uma chave em um array associativo

3

Este código no Bash

s="There are seven pencil"
declare -A A
while IFS= read -rn1 a; do
 [ -z "$a" ] || [ -n "${A[$a]}" ] && continue
 printf %s "$a"
 ((A[$a]++))    # A[$a]=x
done <<<"$s"
echo

produz esta linha

Ther a svn pcil

Todos os espaços são impressos. Esse comportamento é documentado ou de alguma outra forma esperado?

Ainda assim, quando ((A[$a]++)) for substituído por A[$a]=x , a saída será alterada para

Ther asvnpcil

Portanto, desta vez apenas o primeiro espaço é impresso.

Qual é a diferença?

Isto está no GNU bash, versão 4.4.12 (1) -release (x86_64-pc-linux-gnu).

Há uma terceira operação para comparar, ou seja, let "A[$a]=x" . Estranhamente, cai em algum lugar entre os dois primeiros. Produz a linha com todos os espaços, ie. %código%. Mas usando a redução da resposta do isaac , ela se comporta como a designação Ther a svn pcil :

$ unset A; declare -A A; let "A[' ']++"; declare -p A
declare -A A=([" "]="1" )

Eventualmente, eu enviei um relatório de bug com isso. Aqui está o tópico.

    
por Tomasz 25.01.2018 / 00:30

1 resposta

2

A questão central é usar a aritmética para declarar uma variável.

Substituir:

(( A[$a]++ ))

com

declare -A A["$a"]=1

E os espaços repetidos são removidos.

Parece-me ser um bug, um espaço não consegue criar a variável:

$ declare -A A; (( A[" "]++ )); declare -p A
declare -A A

Endereçando sua edição depois que postei a resposta acima:

Qual é a diferença?

Que uma atribuição declara a variável como parte da matriz:

$ unset A; declare -A A; A[" "]=1 ; declare -p A
declare -A A=([" "]="1" )

enquanto uma expansão aritmética falha para fazer o equivalente:

$ unset A; declare -A A; (( A[" "]=1 )); declare -p A
declare -A A
    
por 25.01.2018 / 02:13