sh + como usar array no script sh para imprimir todos os valores no array

4

Eu quero usar matrizes no meu script sh .

Minha meta é criar uma matriz com os valores a b c e imprimir todos os valores na matriz.

Consegui imprimir cada array, mas não consegui imprimir todos os valores no array.

Exemplo a seguir:

Defina cada valor em arr :

n=1
eval arr$n=a
n=2
eval arr$n=b
n=3
eval arr$n=c

Imprima cada valor de arr :

n=1
eval echo \$arr$n
a
n=2
eval echo \$arr$n
b
n=3
eval echo \$arr$n
c

Agora quero imprimir todos os valores em $arr e, em vez de a b c , obtenho:

n="*"
eval echo \$arr$n
{*}*

Os valores devem ser a b c .

    
por maihabunash 03.07.2014 / 09:27

3 respostas

6

sh não suporta array e seu código não cria uma matriz. Ela criou três variáveis arr1 , arr2 , arr3 .

Para inicializar um elemento de matriz em um shell ksh -like, você deve usar a sintaxe array[index]=value . Para obter todos os elementos na matriz, use ${array[*]} ou ${array[@]} .

Tente:

n=1
eval arr[$n]=a
n=2
eval arr[$n]=b
n=3
eval arr[$n]=c

n=1
eval echo \${arr[$n]}
n=2
eval echo \${arr[$n]}
n=3
eval echo \${arr[$n]}

n='*'

eval echo \${arr[$n]}
    
por 03.07.2014 / 09:47
11

Pouco tarde, mas não vejo a resposta sh ideal aqui, então vou entrar em cena. Se você não precisa assinar, então sh efetivamente suporta as matrizes. Apenas os suporta como strings separadas por espaço. Você pode imprimir todo o conteúdo deles, "empurrar" para eles ou iterá-los bem.

Veja um pouco de código de exemplo:

NAMES=""
NAMES="${NAMES} MYNAME"
NAMES="${NAMES} YOURNAME"
NAMES="${NAMES} THEIRNAME"

echo 'One at a time...'
for NAME in ${NAMES}; do
    echo ${NAME};
done

echo 'All together now!'
echo ${NAMES}

Quais resultados:

One at a time...
MYNAME
YOURNAME
THEIRNAME
All together now!
MYNAME YOURNAME THEIRNAME

Agora, eu disse que ele não suporta sub-script, mas com um pouco de cut magic e usando o espaço como um delimitador adequado, você pode imitar isso. Se adicionarmos isso ao final do nosso exemplo acima:

echo 'Get the second one'
echo ${NAMES} | cut -d' ' -f2

echo 'Add one more...'
NAMES="${NAMES} TOM"

echo 'Grab the third one'
echo ${NAMES} | cut -d' ' -f3

E corra, nós temos:

Get the second one
YOURNAME
Add one more...
Grab the third one
THEIRNAME

Qual é o que esperamos!

No entanto, uma string com um espaço pode causar um problema e interromper completamente o sub-script.

Então, realmente a melhor afirmação é: Arrays não são óbvios em sh e é difícil lidar com arrays de strings com espaços. Se você não precisa fazer isso (por exemplo, uma matriz de nomes de host para a qual deseja implantar), o sh ainda é uma excelente ferramenta para o trabalho.

    
por 15.11.2016 / 22:21
0

Concordo que a resposta correta é encontrar uma abordagem diferente. Obtenha um shell melhor, mude para outra linguagem de script (talvez perl ou python), ou repensar seu design. Mas, para obter uma lista dos valores de todas as variáveis cujos nomes começam com arr , você pode usar

set | sed -n '/^arr[^=]*=/s///p'

Isto irá listá-los em linhas separadas. Para colocá-los todos em uma linha, use

echo $(set | sed -n '/^arr[^=]*=/s///p')

Não que isso os classifique em ordem lexicográfica, então arr10arr19 aparecerá entre arr1 e arr2 . (A mesma coisa acontece se você tiver arquivos nomeados maih1 , maih2 ,…, maih10 ,…, maih19 .) Se você souber antecipadamente quantos elementos da matriz você terá, você pode consertar isso usando zeros à esquerda; por exemplo, arr01 . arr02 ,…, te levará até 99 .

P.S. O truque com set | sed … falhará se algum dos valores das variáveis contiver nova (s) linha (s).

    
por 03.07.2014 / 18:48