web-dev-qa-db-fra.com

sh + Comment utiliser le tableau dans SHAY Script afin d'imprimer toutes les valeurs de tableau

Je veux utiliser tableaux dans mon SH Script.

Ma cible est de créer un tableau avec les valeurs a b c et imprimer toutes les valeurs dans le tableau.

J'ai réussi à imprimer chaque tableau, mais j'ai échoué à imprimer toutes les valeurs de la matrice.

Exemple suivant:

Définissez chaque valeur en Ar:

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

Imprimer chaque valeur de Ar:

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

Maintenant, je veux imprimer toutes les valeurs de $arr et au lieu de a b c Je reçois:

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

Les valeurs doivent être a b c.

7
maihabunash

sh ne prend pas en charge tablea et votre code ne crée pas de tableau. Il a créé trois variable arr1, arr2, arr3.

Pour initialiser un élément de tableau dans une coquille ksh, vous devez utiliser la syntaxe array[index]=value. Pour obtenir tout élément de tableau, utilisez ${array[*]} ou ${array[@]}.

Essayer:

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]}
7
cuonglm

Peu de retard, mais je ne vois pas l'idéal sh _ Répondez ici, donc je vais faire chime. Si vous n'avez pas besoin de souscription, alors sh efficacement Do Tableaux de support. Cela les supporte simplement comme des chaînes séparées de l'espace. Vous pouvez imprimer tout le contenu de ceux-ci, "poussez-le" à eux ou les ithéter à travers eux aussi bien.

Voici un peu de code de l'échantillon:

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}

Quelles sorties:

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

Maintenant, j'ai dit qu'il ne prend pas en charge les sous-scripts, mais avec un peu de cut magique et en utilisant l'espace comme un délimiteur approprié, vous pouvez absolument imiter cela. Si nous ajoutons cela au bas de notre exemple ci-dessus:

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

Et courez-le, nous obtenons:

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

C'est ce que nous attendions!

Cependant, une chaîne avec un espace peut provoquer un problème et brisera complètement la sous-script.

Donc, vraiment la meilleure déclaration est la suivante: les tableaux sont non évidents dans sh et de manipulation de tableaux de chaînes avec des espaces sont difficiles. Si vous n'avez pas besoin de le faire (par exemple, un tableau de noms d'hôte que vous souhaitez déployer), alors sh est toujours un outil fine pour le travail.

15
hjc1710

Je conviens que la bonne réponse est de trouver une approche différente. Obtenez une meilleure coque, passez à un autre langage de script (peut-être Perl ou Python) ou repenser votre conception. Mais pour obtenir une liste des valeurs de toutes les variables dont les noms commencent par arr, vous pouvez utiliser

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

Cela les listera sur des lignes séparées. Pour les faire tous sur une ligne, utilisez

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

Pas que cela les triera dans l'ordre lexicographique, alors arr10 ... arr19 apparaîtra entre arr1 et arr2. (La même chose se produit si vous avez des fichiers nommés maih1, maih2, ..., maih10, ..., maih19.) Si vous savez à l'avance combien d'éléments de tableau vous allez avoir, vous pouvez résoudre ce problème en utilisant des zéros de premier plan; par exemple., arr01. arr02, ..., vous mènera jusqu'à 99.

P.s. Le tour avec set | sed … échouera si l'une des valeurs des variables contient des nouvelles lignes.

0
Scott