A contagem de uma matriz tem o dobro do número esperado de elementos

2

Por que bash parece contar as palavras em uma matriz em vez do número de elementos?

touch '1 red' '2 orange' '3 yellow'        # Three filenames, each of two words

files=( * )                                # Get the set of files
echo "#files is ${#files}"

for (( i=0; i <= ${#files}; i++ ))
do
    printf "%d\t%s\n" $i "${files[$i]}"
done

A saída disso parece "errada". Para iniciantes, ${#files} contém 5 , mostrando que há seis elementos em ${files[@]} . No entanto, apenas os elementos 0 , 1 e 2 de ${files[@]} contêm dados, e esses contêm os nomes de arquivos corretos:

#files is 5
0       1 red
1       2 orange
2       3 yellow
3
4
5

Eu esperava que ${files[@]} contivesse as seis palavras 1 , red , 2 , orange , 3 e yellow , ou ${#files} 2 . Não este cenário misto.

Alguém pode lançar alguma luz sobre isso para mim, por favor?

    
por roaima 12.10.2016 / 16:24

2 respostas

2

${#files} é o comprimento do primeiro elemento da matriz, ou seja, o comprimento de 1 red . Qual é cinco.

No manual :

${#name[subscript]} expands to the length of ${name[subscript]}. If subscript is ‘@’ or ‘*’, the expansion is the number of elements in the array. [...]
Referencing an array variable without a subscript is equivalent to referencing with a subscript of 0.

Então, ${#files} = ${#files[0]} . Mas ${#files[@]} ou ${#files[*]} fornecem o número de elementos na matriz.

(Não tem nada a ver com o número de palavras, mas se você expandir ${files[*]} sem aspas, você obterá a palavra usual dividindo todos os valores.)

    
por 12.10.2016 / 16:42
2

Altere ${#files}" para ${#files[@]}"

Você está recebendo 5 de ${#files}" porque esse é o primeiro arquivo.
Equivalente a ${files[0]} , que se chama '1 vermelho'.
Essa string contém 5 caracteres.

O loop falha para o mesmo problema, itera de 1 a 5.
No entanto, os elementos 3, 4 e 5 são simplesmente nulos (não definidos).

    
por 12.10.2016 / 16:41

Tags