Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 26/12/2022, à 22:16

Jarodd

[Résolu] Bash : créer un tableau avec plusieurs dimensions

Bonjour,

J'essaye de me faire un petit script bash (je suis sur la version 5.0.17).
Mon but de d'automatiser des traitements sur des disques durs, avec du mkdir, cp/mv, voire rsync.

Pour représenter le résultat souhaité :

- disques
- ____ d1
- ________ name = "Mon disque 1"
- ________ path = "/path/to/disk1"
- ________options = ""
- ____ d2
- ________ name = "Mon disque 2"
- ________ path = "/path/to/disk2"
- ________options = ""

Je voudrais avoir ça dans un fichier de config, pour gérer les disques sans modifier le script (ajout d'un disque d3 pour un nouveau disque).
Pour cela, j'essaye de déclarer mes différents disques avec dans la 1e dimension du tableau : une clé d'identification du disque, et en valeur les nom, chemin et options (pour un traitement particulier pour ce disque par exemple).

Je n'ai pas réussi à créer d'un coup toutes les dimensions (le web regorge de ressources pour créer des tableau à 1 dimension, ou pour plusieurs dynamiquement dans une boucle par exemple, mais je n'ai rien trouvé dans mon cas, pour déclarer les clés valeurs à différents niveaux).
J'ai essayé ceci (création de sous-tableau pour chaque disque, pour au final créer un tableau global) :

#!/bin/bash

declare -A d1=( [name]="Mon disque 1" [path]="/path/to/disk1/" [options]="" )
echo "${d1[name]}"
echo "${d1[path]}"
echo "${d1[options]}"

declare -A d2=( [name]="Mon disque 2" [path]="/path/to/disk2/" [options]="" )
echo "${d2[name]}"
echo "${d2[path]}"
echo "${d2[options]}"

declare -A disques
disques[d1]=${d1}
disques[d2]=${d2}
echo "${disques[@]}";

exit 1

Les echo d1 et d2 affichent les bonnes valeurs, mais je n'arrive pas à avoir un tableau global avec disks qui reprend les précédentes valeurs, sur lequel je pourrai ensuite boucler.

J'espère que ma demande est compréhensible. Merci pour votre aide.

Edit : résolu, voir la syntaxe en #6

Dernière modification par Jarodd (Le 30/12/2022, à 13:41)


Ubuntu 22.04.3 LTS (64 bits)

Hors ligne

#2 Le 27/12/2022, à 00:32

kamaris

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

Ce que tu veux faire c'est un tableau de structures, mais il n'y a pas de structures en bash.
Sinon, tu peux inverser la logique : un tableau par propriété, puisqu'elles ne devraient pas changer, contrairement au nombre de disques.

Hors ligne

#3 Le 27/12/2022, à 05:00

Watael

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

disques[d1]=${d1[@]}

1- sans [@], les accolades sont inutiles
2- les éléments d'un tableau sont des "variables plates"

peut-être avec des références :

$ disks=( d1 d2 dN+1 )
$ declare -A d1=( [name]="Mon disque 1" [path]="/path/to/disk1/" [options]="" )
$
$ declare -n disk="${disks[0]}"
$ for i in "${!disk[@]}"; do echo "$i = ${disk[$i]}"; done
options = 
path = /path/to/disk1/
name = Mon disque 1
$

edit : ajout accolade manquante : "${disk[0]}"

Dernière modification par Watael (Le 28/12/2022, à 18:04)


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#4 Le 30/12/2022, à 12:32

Jarodd

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

Bonjour,
Je ne suis pas sûr de bien comprendre. À quoi sert la ligne "declare -n" ? Mon but est d'avoir une liste dynamique avec X disques, le script ne sait pas combien, donc je ne peux pas mettre X lignes en changeant la valeur de 0.

disks=( d1 d2 )
declare -A d1=( [name]="Mon disque 1" [path]="/path/to/disk1/" )
declare -A d2=( [name]="Mon disque 2" [path]="/path/to/disk2/" )
declare -n disk="${disks[0]}"
for i in "${!disk[@]}"; do echo "$i = ${disk[$i]}"; done
exit 1

J'ai bien :

path = /path/to/disk1/
name = Mon disque 1

Mais rien pour le 2e disque.


Ubuntu 22.04.3 LTS (64 bits)

Hors ligne

#5 Le 30/12/2022, à 12:58

Watael

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

il faut boucler sur disks pour itérer declare -n sur chaque élément de ce tableau indexé.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#6 Le 30/12/2022, à 13:40

Jarodd

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

Oui cela fonctionne,  merci !

declare -A d1=( [name]="Mon disque 1" [path]="/path/to/disk1/" )
declare -A d2=( [name]="Mon disque 2" [path]="/path/to/disk2/" )
declare -A d3=( [name]="Mon disque 3" [path]="/path/to/disk3/" )
disks=( d1 d2 d3 )

for i in "${!disks[@]}"
do
    declare -n disk="${disks[$i]}"
    echo "$i = ${disks[$i]}"
    name=${disk[name]}
    path=${disk[path]}
    echo "name=$name, path=$path"
done

Résultat :

0 = d1
name=Mon disque 1, path=/path/to/disk1/
1 = d2
name=Mon disque 2, path=/path/to/disk2/
2 = d3
name=Mon disque 3, path=/path/to/disk3/

Merci bcp pour votre aide smile

Dernière modification par Jarodd (Le 30/12/2022, à 13:41)


Ubuntu 22.04.3 LTS (64 bits)

Hors ligne

#7 Le 31/12/2022, à 09:43

Hizoka

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

Salut,
histoire de chipoter, on peut se passer de disks=( d1 d2 d3 ) :

declare -A d1=( [name]="Mon disque 1" [path]="/path/to/disk1/" )
declare -A d2=( [name]="Mon disque 2" [path]="/path/to/disk2/" )
declare -A d3=( [name]="Mon disque 3" [path]="/path/to/disk3/" )

for i in "${!d@}"
do
    declare -n disk="${i}"
    echo "$i = $i"
    name=${disk[name]}
    path=${disk[path]}
    echo "name=$name, path=$path"
done

bon, il faudra peut être des noms de variables plus explicite que d1 a d3 pour ne pas risque que ${!d@} ramène toutes les variables commençants par d tongue


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#8 Le 31/12/2022, à 10:13

Watael

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

man bash a écrit :

      ${!préfixe*}
       ${!préfixe@}

              Noms correspondant au préfixe.
              Se développe en noms des variables dont les noms commencent par préfixe, séparés par le premier caractère de la variable spéciale IFS.
              Si @ est utilisé et que le développement apparaît entre guillemets doubles, chaque nom de variable se développe séparément.

+1


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#9 Le 31/12/2022, à 17:43

Jarodd

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

Bonjour,
d1 d2 c'était des exemples "génériques" pour expliquer ma problématique, ce n'est pas le vrai nom de mes disques smile Mais je note le point (j'ai du mal avec la syntaxe bash !).


Ubuntu 22.04.3 LTS (64 bits)

Hors ligne

#10 Le 02/01/2023, à 16:55

Jarodd

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

Bonjour,
Je reviens sur le fait de se passer de disks=( d1 d2 d3 ). Dans ce cas que dois-je mettre dans la ligne for ? Si je n'ai ni préfixe, ni tableau "global" avec tous les disques ?


Ubuntu 22.04.3 LTS (64 bits)

Hors ligne

#11 Le 02/01/2023, à 18:38

Watael

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

comment connais-tu les disques ?


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#12 Le 02/01/2023, à 19:24

Jarodd

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

Je les déclare dans au début du script (ou un fichier txt) comme dans le message #6, avec le declare -A.


Ubuntu 22.04.3 LTS (64 bits)

Hors ligne

#13 Le 02/01/2023, à 20:06

Watael

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

je ne vois pas où est le problème, alors, puisque c'est toi qui rédige le script : tu connais les tableaux associatifs, et tu peux donc créer des noms avec un préfixe qui sera repris comme l'a montré Hizoka.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#14 Le 02/01/2023, à 20:51

Jarodd

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

Ok je vois cela oblige à avoir un préfixe. Je demandais dans le cas où on n'en a pas.


Ubuntu 22.04.3 LTS (64 bits)

Hors ligne

#15 Le 02/01/2023, à 20:55

Watael

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

pourquoi t'en priver ?
puisque c'est toi qui a la main, autant être cohérent. smile

sinon, comme je te l'ai demandé, il faut nous dire/montrer comment t'arrive ce que tu dois traiter.


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#16 Le 02/01/2023, à 21:10

Jarodd

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

J'ai montré ce que j'avais :

declare -A d1=( [name]="Mon disque 1" [path]="/path/to/disk1/" )
declare -A d2=( [name]="Mon disque 2" [path]="/path/to/disk2/" )
declare -A d3=( [name]="Mon disque 3" [path]="/path/to/disk3/" )

Dans mon cas personnel, je choisis les noms, donc je vais ajouter un préfixe.
Ma question concerne le cas où je ne choisis pas ces noms, donc comment faire avec (au hasard) :

declare -A foo=( [name]="Mon disque foo" [path]="/path/to/foo/" )
declare -A bar=( [name]="bar" [path]="/path/to/bar/" )
declare -A baz=( [name]="baz" [path]="/path/to/baz/" )

Ici pas de préfixe, donc je ne vois pas quoi mettre dans le for. Ou alors je n'ai pas compris ta remarque.


Ubuntu 22.04.3 LTS (64 bits)

Hors ligne

#17 Le 02/01/2023, à 21:27

Watael

Re : [Résolu] Bash : créer un tableau avec plusieurs dimensions

mais pourquoi tu ne peux pas choisir ?
et pourquoi y a-t-il un pingouin qui choisit à ta place de manière incohérente ?

au pire, on pourrait parcourir la sortie de declare -pA...


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne