Eu quero fazer algo assim:
foo=( )
foo[0]="bar"
foo[35]="baz"
for((i=0;i<${#foo[@]};i++))
do
echo "$i: ${foo[$i]}"
done
# Output:
# 0: bar
# 1:
Então eu tentei fazer um loop através dele usando for:
foo=( )
foo[0]="bar"
foo[35]="baz"
for i in ${foo[@]}
do
echo "?: $i"
done
# Output:
# ?: bar
# ?: naz
mas aqui não sei o valor do índice.
Eu sei que você poderia algo como
foo=( )
foo[0]="bar"
foo[35]="baz"
declare -p foo
# Output:
# declare -a foo='([0]="bar" [35]="baz")'
mas você não pode fazer isso de outra maneira?
(a b c)
para convertê-lo em uma matriz.[@]
e aspas duplas significa que não é uma "lista de palavras separadas por espaço". Você obtém a lista de chaves de matriz reais, mesmo que as chaves individuais contenham espaços em branco.The use of [@] and double quotes means it's not a "space separated list of words"
"${foo[@]}"
pega a variável (array)foo
e a expande como uma matriz, mantendo a identidade de seus elementos, ou seja, não os dividindo em espaços em branco. Sefoo=(x 'y z')
, entãof "${foo[@]}"
chamaf
com dois argumentos,x
e'y z'
. Consultas de metadados como"${!foo[@]}"
e"${#foo[@]}"
agem da mesma formafoo
como uma matriz."${!foo[@]}"
é a lista de todos os índices definidos na matriz".você sempre pode usar o parâmetro de iteração:
fonte
((ITER++))
no bash modernofonte
No bash 4, você pode usar matrizes associativas:
No bash 3, isso funciona (também funciona no zsh):
fonte
fonte
Truque simples de uma linha para descarregar array
Eu adicionei um valor com espaços:
Eu, para despejar rapidamente festançamatrizes ou matrizes associativas que eu uso
Este comando de uma linha:
Renderizará:
Explicado
printf "%s\n" "${!foo[@]}"
imprimirá todas as chaves separadas por uma nova linha ,printf "%s\n" "${foo[@]}"
imprimirá todos os valores separados por uma nova linha ,paste <(cmd1) <(cmd2)
irá mesclar a saída decmd1
ecmd2
linha por linha.Tunning
Isso pode ser ajustado pelo
-d
switch:ou até:
A matriz associativa funcionará da mesma maneira:
Problema com novas linhas ou caracteres especiais
Infelizmente, há pelo menos uma condição para que isso não funcione mais: quando a variável contém nova linha:
O comando
paste
mesclará linha por linha, portanto, a saída ficará errada:Para este trabalho, você pode usar em
%q
vez do%s
segundoprintf
comando (e aspas):Tornará perfeito:
De
man bash
:fonte
printf "%q\n" "${var[@]}"
positivo para newline foi meu problema!