IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Discussion :

Tableaux de tableaux en Bash : possible 'nativement'


Sujet :

Contribuez

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 15
    Points : 2
    Points
    2
    Par défaut Tableaux de tableaux en Bash : possible 'nativement'
    Bonjour, Bash permet de stocker et de manipuler simplement et nativement des tableaux de tableaux (indicés, associatifs, hybrides), et même récursivement des tableaux de tableaux de tableaux etc. C'est important, par exemple ça simplifie beaucoup la manipulation d'objets plus évolués comme les listes ou les arbres.

    Cette possibilité est restée méconnue à cause d'une difficulté liée à l'affectation : Bash ne permet pas d'affecter directement un tableau T comme 'valeur' d'un autre tableau, on ne peut pas écrire par exemple t[2]=$T. Pour pallier à ce manque, une fonction "tableau" a été ajoutée (voir script ci-dessous), et l'écriture de l'affectation devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t[2]=$(tableau T)   # stockage dans t[2] du tableau T
    Pour retrouver ces valeurs (qui sont des tableaux), il faut utiliser des variables déclarées (même pour les tableaux indicés) dont l'affectation doit se faire au moment de la déclaration. Avec notre exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    declare -a X=${t[2]}   # récupération dans le tableau X du tableau stocké dans t[2] ; utiliser "-A" si t[2] est un tableau associatif
    Le script suivant montre différents cas d'utilisation. Pour se convaincre que Bash gère bien 'nativement' les tableaux de tableaux, il faut regarder comment il les stocke. Par exemple, il est possible de visualiser le tableau k (qui est un tableau de tableaux de tableaux) en dé-commentant la ligne 82.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    # Tableaux de tableaux en Bash
    # ============================
     
    # Le Bash gère 2 types de tabeaux :
     
    # 1 - les tableaux indicés (leur déclaration n'est pas obligatoire)
    a=(1 2 "u v" 3)                          # ou :   declare -a a=(1 2 "u v" 3)
    b=(4 5 "w x")
     
    # 2 - les tableaux associatifs (leur déclaration est obligatoire)
    declare -A e=([x]="iks" [y]="i grec")    # ou :   e[x]="iks" ; e[y]="i grec"
    declare -A f=([un]="one" [deux]="two")
     
    # Affichage d'un tableau $1 avec la même forme que quand on l'affecte globalement
    # -------------------------------------------------------------------------------
    tableau () { declare -p $1 \
               | awk '{typ=substr($0,10,1) ;                          # a=indicé A=associatif
                       sub("^[^=]*=.","",$0) ; sub(".$","",$0)        # suppression du "declare ..." et des quotes
                       if (typ=="a") gsub("\\[[^\\]]*\\]=","",$0) ;   # si indicé, suppression des index
                       print $0
                      }' 
               }
     
    echo
    echo "0 - Test de la fonction tableau"
    echo "-------------------------------"
    tableau a ; tableau b
    tableau e ; tableau f
     
    echo
    echo "1 - Tableaux indices de tableaux indices"
    echo "----------------------------------------"
     
    c[0]=$(tableau a) 
    c[1]=$(tableau b)  # on peut aussi ecrire directement   c=("$(tableau a)" "$(tableau b)"
     
    # Lecture de la 2eme valeur (donc un tableau indicé) 
    declare -a d=${c[1]}
    # d=${c[1]}  ne marche jamais, meme s'il y a un "declare -a d" préalable
     
    # Lecture des valeurs de ce tableau
    echo d0= ${d[0]}
    echo d1= ${d[1]}
    echo d2= ${d[2]}
     
    echo
    echo "2 - Tableaux indices de tableaux associatifs"
    echo "--------------------------------------------"
     
    g[0]=$(tableau e)
    g[1]=$(tableau f)
     
    # Lecture de la 2eme valeur (donc un tableau associatif) 
    declare -A h=${g[1]}
     
    # Lecture des valeurs de ce tableau
    echo ${h[un]}
    echo ${h[deux]}
     
    echo
    echo "3 - Tableaux associatifs de tableaux associatifs"
    echo "------------------------------------------------"
     
    declare -A i
    i[alpha]=$(tableau e)
    i[beta]=$(tableau f)
     
    # Dans ce tableau de tableaux, lecture de la 2eme valeur (donc un tableau associatif) 
    declare -A j=${i[beta]}
     
    # Lecture des valeurs de ce tableau
    echo ${j[un]}
    echo ${j[deux]}
     
    echo
    echo "4 - Tableaux associatifs de tableaux associatifs de tableaux associatifs"
    echo "------------------------------------------------------------------------"
     
    declare -A k
    k[premier]=$(tableau i)
    k[second]=$(tableau j)
    # tableau k
     
    # Dans ce tableau de tableaux de tableaux, lecture de la 1ère valeur (donc un tableau de tableaux)
    declare -A l=${k[premier]}
     
    # Puis dans cette valeur, lecture de la 2ème valeur (donc un tableau associatif)
    declare -A m=${l[beta]}
     
    # Lecture des valeurs de ce tableau associatif
    echo ${m[un]}
    echo ${m[deux]}
    Cordialement

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 549
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 378
    Points
    19 378
    Par défaut
    Bonjour,

    quitte à faire une démonstration de bash, autant tout faire en bash :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tableau() { declare -n t=$1; for i in "${!t[@]}"; do echo "[$i]=\"${t["$i"]}\""; done;}
    si j'ai bien compris, cela ne constitue pas des tableaux de tableaux : les tableaux originaux sont "applatis" dans des éléments du "tableau de tableaux", c'est à dire une variable.
    on ne peut pas accéder aux éléments des tableaux dans le tableau de tableaux.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 549
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 549
    Points : 19 378
    Points
    19 378
    Par défaut
    je ne suis pas débordé en ce moment, donc j'ai fait un test du script :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    /tmp/arrArr.sh                                                                                                                                                                                                                      [14/14]
     
    0 - Test de la fonction tableau                                                                                                                                                                                                                                           
    -------------------------------                                                                                                                                                                                                                                           
    "1" "2" "u v" "3"                                                                                                                                                                                                                                                         
    "4" "5" "w x"                                                                                                                                                                                                                                                             
    [x]="iks" [y]="i grec"                                                                                                                                                                                                                                                    
    [deux]="two" [un]="one"                                                                                                                                                                                                                                                   
     
    1 - Tableaux indices de tableaux indices                                                                                                                                                                                                                                  
    ----------------------------------------                                                                                                                                                                                                                                  
    d0= "4" "5" "w x"                                                                                                                                                                                                                                                         
    d1=                                                                                                                                                                                                                                                                       
    d2=                                                                                                                                                                                                                                                                       
     
    2 - Tableaux indices de tableaux associatifs
    --------------------------------------------
     
     
     
    3 - Tableaux associatifs de tableaux associatifs
    ------------------------------------------------
     
     
     
    4 - Tableaux associatifs de tableaux associatifs de tableaux associatifs
    ------------------------------------------------------------------------


    bien que d soit declare en tant que tableau (superflue, puisque c'est un tableau indexé), son assignation est celle d'une variable, c'est équivalent àtout le reste du tableau d[1], d[2] n'existe pas.

    copie à revoir ! -1
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  4. #4
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 277
    Points : 12 722
    Points
    12 722
    Par défaut
    Autant utiliser ksh93, au moins, lui supporte nativement les tableaux multi-dimension qu'ils soient indexés ou associatifs.
    Cordialement.

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Tu aurais un exemple ? Parce que partout où je cherche on dit que ce n'est pas possible...
    https://marcg.developpez.com/ksh/
    https://www.developpez.net/forums/d1...-2-dimensions/
    ... et on utilise des solutions à base de eval pour les simuler...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 277
    Points : 12 722
    Points
    12 722
    Par défaut
    Voici pour les indexés:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    $ unset aa
    $ for i in {1..5}
    do
      for j in {1..5}
      do
        for k in {1..5}
        do
          aa[$i][$j][$k]="a${k}b${i}c${j}"
        done
      done
    done
     
    $ typeset -p aa
    typeset -a aa=([1]=([1]=([1]=a1b1c1 [2]=a2b1c1 [3]=a3b1c1 [4]=a4b1c1 [5]=a5b1c1) [2]=([1]=a1b1c2 [2]=a2b1c2 [3]=a3b1c2 [4]=a4b1c2 [5]=a5b1c2) [3]=([1]=a1b1c3 [2]=a2b1c3 [3]=a3b1c3 [4]=a4b1c3 [5]=a5b1c3) [4]=([1]=a1b1c4 [2]=a2b1c4 [3]=a3b1c4 [4]=a4b1c4 [5]=a5b1c4) [5]=([1]=a1b1c5 [2]=a2b1c5 [3]=a3b1c5 [4]=a4b1c5 [5]=a5b1c5) ) [2]=([1]=([1]=a1b2c1 [2]=a2b2c1 [3]=a3b2c1 [4]=a4b2c1 [5]=a5b2c1) [2]=([1]=a1b2c2 [2]=a2b2c2 [3]=a3b2c2 [4]=a4b2c2 [5]=a5b2c2) [3]=([1]=a1b2c3 [2]=a2b2c3 [3]=a3b2c3 [4]=a4b2c3 [5]=a5b2c3) [4]=([1]=a1b2c4 [2]=a2b2c4 [3]=a3b2c4 [4]=a4b2c4 [5]=a5b2c4) [5]=([1]=a1b2c5 [2]=a2b2c5 [3]=a3b2c5 [4]=a4b2c5 [5]=a5b2c5) ) [3]=([1]=([1]=a1b3c1 [2]=a2b3c1 [3]=a3b3c1 [4]=a4b3c1 [5]=a5b3c1) [2]=([1]=a1b3c2 [2]=a2b3c2 [3]=a3b3c2 [4]=a4b3c2 [5]=a5b3c2) [3]=([1]=a1b3c3 [2]=a2b3c3 [3]=a3b3c3 [4]=a4b3c3 [5]=a5b3c3) [4]=([1]=a1b3c4 [2]=a2b3c4 [3]=a3b3c4 [4]=a4b3c4 [5]=a5b3c4) [5]=([1]=a1b3c5 [2]=a2b3c5 [3]=a3b3c5 [4]=a4b3c5 [5]=a5b3c5) ) [4]=([1]=([1]=a1b4c1 [2]=a2b4c1 [3]=a3b4c1 [4]=a4b4c1 [5]=a5b4c1) [2]=([1]=a1b4c2 [2]=a2b4c2 [3]=a3b4c2 [4]=a4b4c2 [5]=a5b4c2) [3]=([1]=a1b4c3 [2]=a2b4c3 [3]=a3b4c3 [4]=a4b4c3 [5]=a5b4c3) [4]=([1]=a1b4c4 [2]=a2b4c4 [3]=a3b4c4 [4]=a4b4c4 [5]=a5b4c4) [5]=([1]=a1b4c5 [2]=a2b4c5 [3]=a3b4c5 [4]=a4b4c5 [5]=a5b4c5) ) [5]=([1]=([1]=a1b5c1 [2]=a2b5c1 [3]=a3b5c1 [4]=a4b5c1 [5]=a5b5c1) [2]=([1]=a1b5c2 [2]=a2b5c2 [3]=a3b5c2 [4]=a4b5c2 [5]=a5b5c2) [3]=([1]=a1b5c3 [2]=a2b5c3 [3]=a3b5c3 [4]=a4b5c3 [5]=a5b5c3) [4]=([1]=a1b5c4 [2]=a2b5c4 [3]=a3b5c4 [4]=a4b5c4 [5]=a5b5c4) [5]=([1]=a1b5c5 [2]=a2b5c5 [3]=a3b5c5 [4]=a4b5c5 [5]=a5b5c5) ) )
    $ echo ${aa[1][1][1]}
    a1b1c1
    $ echo ${aa[1][2][1]}
    a1b1c2
    $ echo ${aa[1][2][3]}
    a3b1c2
    Pour les tableaux associatifs, il y a une subtilité lors de la création, c'est qu'il faut déclaré pour chaque "dimension" que c'est un tableau associatif, donc, en se basant sur l'exemple précédent:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    $ unset aa
    $ typeset -A aa
    $ for i in {1..5}
    do 
      typeset -A aa[xx${i}]
      for j in {1..5}
      do
        typeset -A aa[xx${i}][yy${j}]
        for k in {1..5}
        do
          aa[xx${i}][yy${j}][zz${k}]="a${k}b${i}c${j}"
        done
      done
    done
     
    $ typeset -p aa
    typeset -A aa=([xx1]=([yy1]=([zz1]=a1b1c1 [zz2]=a2b1c1 [zz3]=a3b1c1 [zz4]=a4b1c1 [zz5]=a5b1c1) [yy2]=([zz1]=a1b1c2 [zz2]=a2b1c2 [zz3]=a3b1c2 [zz4]=a4b1c2 [zz5]=a5b1c2) [yy3]=([zz1]=a1b1c3 [zz2]=a2b1c3 [zz3]=a3b1c3 [zz4]=a4b1c3 [zz5]=a5b1c3) [yy4]=([zz1]=a1b1c4 [zz2]=a2b1c4 [zz3]=a3b1c4 [zz4]=a4b1c4 [zz5]=a5b1c4) [yy5]=([zz1]=a1b1c5 [zz2]=a2b1c5 [zz3]=a3b1c5 [zz4]=a4b1c5 [zz5]=a5b1c5) ) [xx2]=([yy1]=([zz1]=a1b2c1 [zz2]=a2b2c1 [zz3]=a3b2c1 [zz4]=a4b2c1 [zz5]=a5b2c1) [yy2]=([zz1]=a1b2c2 [zz2]=a2b2c2 [zz3]=a3b2c2 [zz4]=a4b2c2 [zz5]=a5b2c2) [yy3]=([zz1]=a1b2c3 [zz2]=a2b2c3 [zz3]=a3b2c3 [zz4]=a4b2c3 [zz5]=a5b2c3) [yy4]=([zz1]=a1b2c4 [zz2]=a2b2c4 [zz3]=a3b2c4 [zz4]=a4b2c4 [zz5]=a5b2c4) [yy5]=([zz1]=a1b2c5 [zz2]=a2b2c5 [zz3]=a3b2c5 [zz4]=a4b2c5 [zz5]=a5b2c5) ) [xx3]=([yy1]=([zz1]=a1b3c1 [zz2]=a2b3c1 [zz3]=a3b3c1 [zz4]=a4b3c1 [zz5]=a5b3c1) [yy2]=([zz1]=a1b3c2 [zz2]=a2b3c2 [zz3]=a3b3c2 [zz4]=a4b3c2 [zz5]=a5b3c2) [yy3]=([zz1]=a1b3c3 [zz2]=a2b3c3 [zz3]=a3b3c3 [zz4]=a4b3c3 [zz5]=a5b3c3) [yy4]=([zz1]=a1b3c4 [zz2]=a2b3c4 [zz3]=a3b3c4 [zz4]=a4b3c4 [zz5]=a5b3c4) [yy5]=([zz1]=a1b3c5 [zz2]=a2b3c5 [zz3]=a3b3c5 [zz4]=a4b3c5 [zz5]=a5b3c5) ) [xx4]=([yy1]=([zz1]=a1b4c1 [zz2]=a2b4c1 [zz3]=a3b4c1 [zz4]=a4b4c1 [zz5]=a5b4c1) [yy2]=([zz1]=a1b4c2 [zz2]=a2b4c2 [zz3]=a3b4c2 [zz4]=a4b4c2 [zz5]=a5b4c2) [yy3]=([zz1]=a1b4c3 [zz2]=a2b4c3 [zz3]=a3b4c3 [zz4]=a4b4c3 [zz5]=a5b4c3) [yy4]=([zz1]=a1b4c4 [zz2]=a2b4c4 [zz3]=a3b4c4 [zz4]=a4b4c4 [zz5]=a5b4c4) [yy5]=([zz1]=a1b4c5 [zz2]=a2b4c5 [zz3]=a3b4c5 [zz4]=a4b4c5 [zz5]=a5b4c5) ) [xx5]=([yy1]=([zz1]=a1b5c1 [zz2]=a2b5c1 [zz3]=a3b5c1 [zz4]=a4b5c1 [zz5]=a5b5c1) [yy2]=([zz1]=a1b5c2 [zz2]=a2b5c2 [zz3]=a3b5c2 [zz4]=a4b5c2 [zz5]=a5b5c2) [yy3]=([zz1]=a1b5c3 [zz2]=a2b5c3 [zz3]=a3b5c3 [zz4]=a4b5c3 [zz5]=a5b5c3) [yy4]=([zz1]=a1b5c4 [zz2]=a2b5c4 [zz3]=a3b5c4 [zz4]=a4b5c4 [zz5]=a5b5c4) [yy5]=([zz1]=a1b5c5 [zz2]=a2b5c5 [zz3]=a3b5c5 [zz4]=a4b5c5 [zz5]=a5b5c5) ) )
     
    $ echo ${!aa[@]}   # les hash de la première dimension
    xx1 xx2 xx3 xx4 xx5
    $ echo ${!aa[xx1][@]} # les hash de la seconde dimension
    yy1 yy2 yy3 yy4 yy5
    $ echo ${aa[xx1][yy1][@]} # les valeurs selon la troisième dimension
    a1b1c1 a2b1c1 a3b1c1 a4b1c1 a5b1c1
    Cordialement.

Discussions similaires

  1. Créer des tableaux de tableaux, c'est possible ?
    Par MobyKDIK dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 21/07/2015, 08h32
  2. [Tableaux] toute combinaison de lettres possible
    Par olkabil dans le forum Langage
    Réponses: 5
    Dernier message: 10/06/2008, 16h50
  3. 2 tableaux dans un tableau HTML Possible ?
    Par bilou95 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 17/08/2007, 19h31
  4. [Tableaux] les tableaux
    Par jeanfrancois dans le forum Langage
    Réponses: 2
    Dernier message: 03/03/2006, 11h02
  5. Réponses: 10
    Dernier message: 12/01/2006, 21h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo