Je me demande comment déclarer un tableau 2D en bash et l'initialiser à 0.
En C, cela ressemble à ceci :
int a[4][5] = {0};
Et comment attribuer une valeur à un élément ? Comme en C :
a[2][3] = 3;
Je me demande comment déclarer un tableau 2D en bash et l'initialiser à 0.
En C, cela ressemble à ceci :
int a[4][5] = {0};
Et comment attribuer une valeur à un élément ? Comme en C :
a[2][3] = 3;
On peut les simuler par exemple avec des hachages, mais il faut alors se préoccuper des zéros de tête et de bien d'autres choses. La démonstration suivante fonctionne, mais elle est loin d'être une solution optimale.
#!/bin/bash
declare -A matrix
num_rows=4
num_columns=5
for ((i=1;i<=num_rows;i++)) do
for ((j=1;j<=num_columns;j++)) do
matrix[$i,$j]=$RANDOM
done
done
f1="%$((${#num_rows}+1))s"
f2=" %9s"
printf "$f1" ''
for ((i=1;i<=num_rows;i++)) do
printf "$f2" $i
done
echo
for ((j=1;j<=num_columns;j++)) do
printf "$f1" $j
for ((i=1;i<=num_rows;i++)) do
printf "$f2" ${matrix[$i,$j]}
done
echo
done
l'exemple ci-dessus crée une matrice 4x5 avec des nombres aléatoires et l'imprime transposée, avec le résultat de l'exemple
1 2 3 4
1 18006 31193 16110 23297
2 26229 19869 1140 19837
3 8192 2181 25512 2318
4 3269 25516 18701 7977
5 31775 17358 4468 30345
Le principe est le suivant : Créer un tableau associatif où l'index est une chaîne de caractères comme 3,4
. Les avantages :
30,40,2
pour 3 dimensions.${matrix[2,3]}
L'inconvénient évident de cette méthode est que la longueur d'une dimension ne peut être connue. Néanmoins, elle fonctionne parfaitement dans la plupart des autres scénarios ! Merci !
@Jodes le f1
et f2
contient le format
pour le printf
pour une impression bien alignée. Il pourrait être codé en dur, par exemple printf "%2s"
mais l'utilisation de variables est plus flexible - comme dans l'exemple ci-dessus f1
. Le site width
de la numéro de rang est calculé comme la longueur de $num_rows
variable - par exemple, si le nombre de rangées $num_rows
est 9, sa longueur est 1
le format sera 1+1
donc %2s
. Pour le $num_rows
2500, sa longueur est 4
Le format sera donc %5s
- et ainsi de suite...
Bash ne prend pas en charge les tableaux multidimensionnels.
Vous pouvez cependant la simuler en utilisant l'expansion indirecte :
#!/bin/bash
declare -a a0=(1 2 3 4)
declare -a a1=(5 6 7 8)
var="a1[1]"
echo ${!var} # outputs 6
Les affectations sont également possibles avec cette méthode :
let $var=55
echo ${a1[1]} # outputs 55
Edit 1 : Pour lire un tel tableau à partir d'un fichier, avec chaque ligne sur une ligne, et les valeurs délimitées par des espaces, utilisez ceci :
idx=0
while read -a a$idx; do
let idx++;
done </tmp/some_file
Edit 2 : Déclarer et initialiser a0..a3[0..4]
à 0
tu pourrais courir :
for i in {0..3}; do
eval "declare -a a$i=( $(for j in {0..4}; do echo 0; done) )"
done
Pouvez-vous me montrer comment remplir la "simulation de tableau 2d" ci-dessus à partir d'un fichier-tableau ? Par exemple, j'ai un fichier avec un nombre aléatoire de lignes et dans chaque ligne, 5 nombres délimités par des espaces.
@kobame : J'ai édité la réponse pour fournir une solution à ce que vous demandez. Il lira un tableau 2d avec un nombre variable de lignes et un nombre variable de colonnes, en a0, a1 et ainsi de suite.
Vous pouvez également aborder cette question de manière beaucoup moins intelligente.
q=()
q+=( 1-2 )
q+=( a-b )
for set in ${q[@]};
do
echo ${set%%-*}
echo ${set##*-}
done
bien sûr, une solution à 22 lignes ou une indirection est probablement la meilleure façon de procéder et pourquoi ne pas saupoudrer de l'évaluation un peu partout ?
Où la solution de 22 lignes utilise-t-elle l'indirection ? Pour votre solution, qu'allez-vous faire lorsque vous écrivez un script qui nécessite des entrées/sorties et qu'un utilisateur veut entrer un -
dans le "tableau". De même, si vous souhaitez simuler un tableau, il est probablement plus judicieux d'utiliser la méthode suivante echo ${set//-/ }
au lieu de vos deux.
Je pense que ${set//-/} est probablement une meilleure solution (je ne connais pas les problèmes de portabilité de %% et ##, mais je vous crois). La question "Et si" est très dangereuse, si vous la posez trop souvent, vous vous rendrez compte que vous avez besoin d'une I.A. pour votre analyseur d'options :{p
Comme l'a dit @Alper, Bash ne dispose pas de tableaux multidimensionnels. Vous devez le simuler. Cette page contient un exemple au bas de la page : http://tldp.org/LDP/abs/html/arrays.html
Bash ne supporte pas les tableaux à 2 dimensions, mais il existe des passerelles en fonction de ce que vous voulez. Comme awk
fonctionne en bash et supporte les tableaux 2d. http://www.gnu.org/software/gawk/manual/html_node/Multi_002ddimensional.html
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
3 votes
En rapport : tableaux multidimensionnels en BASH
4 votes
En fait, un tableau multidimensionnel est en réalité (au fond) un tableau unidimensionnel, qui est géré un peu différemment, notamment lorsqu'il s'agit d'accéder à ses éléments. Par exemple, une matrice 3x4 comporte 12 cellules. Les "lignes" sont parcourues avec une boucle externe avec un pas de 3 et les "colonnes" sont parcourues avec une boucle interne avec un pas de 1.