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 14/04/2018, à 16:11

Brice Jeunieaux

[Résolu] Comment affecter une liste à un élément de tableau ?

Bonjour / bonsoir ,

c'est encore moi, pour faire suite à mon "ex" problème, sur le sujet Créer une variable dont le nom dépend d'une autre variable.

Aujourd'hui, j'arrive à afficher mes pages contenant chacune un intervalle de lignes de données de mon fichier .csv ( cool ), mais je continue à rencontrer un problème, car je n'arrive pas, même en utilisant les tableaux associatifs, à affecter une liste à un élément de tableau.


Certes, grâce aux tableaux associatifs, j'arrive à créer des clés dont le nom varie avec les itérations de ma boucle for, mais lorsque je veux affecter une liste à l'élément avec la clé en question, le terminal me dit :

./test2.sh: ligne 12: numPages["Page$a"] : impossible d'affecter une liste à un élément de tableau

J'ai bien compris qu'il était possible qu'avec cette version de Bash, il n'est pas possible de réaliser cela.
Au cas où, ma version de Bash est la 4.4.12(1), mais je ne pense pas que ça ait un lien... hmm


Je pense être obligé de passer par là pour faire mes tableaux multi-dimensionnels, car si je procède de la manière ci-dessous, je ne pense pas pouvoir utiliser des boucles for pour les affectations et traitements :

lettres1=(A B C D E F)
lettres2=(G H I J K L M)
lettres3=(N O P Q R S)
lettres4=(T U V W X Y Z)

tab1=(${lettres1[@]} ${lettres2[@]} ${lettres3[@]} ${lettres4[@]})

Ma question est donc dans le titre, si jamais vous auriez une solution alternative à me proposer, qui aurait l'effet recherché. Merci beaucoup à vous ! big_smile

Dernière modification par Brice Jeunieaux (Le 16/05/2018, à 17:46)

Hors ligne

#2 Le 14/04/2018, à 16:44

erresse

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

Bonjour,
Comme suite à ta conversation précédente, tu dois avoir compris que bash ne sait pas gérer des tableaux multidimensionnels.
Tu parles d'affecter une "liste" à un "élément de tableau"... en bash, la "liste", ça n'existe pas, seul le tableau existe et il ne sait gérer qu'un unique niveau.
On peut ruser en mettant en tableau les noms d'autres tableaux, ce qui peut permettre de traiter les éléments d'un tableau depuis un nom de tableau qui est lui-même contenu dans un tableau. Ça ressemble à une gestion multidimensionnelle, mais en fait les "sous-éléments" ne sont pas contenus dans des éléments du tableau, ils sont dans des tableaux séparés.
Dans ton exemple, si tu enregistres dans tab1 les noms des tableaux lettres1 à lettres4, tu pourrais retrouver les éléments d'une lettresX en cherchant le nom du tableau dans tab1 puis en référençant le tableau lettresX considéré indépendamment.


Plus de 50 ans d'informatique, ça en fait des lignes de commandes en console, mais on n'avait pas le choix...
Excellente raison pour, aujourd'hui qu'on le peut, utiliser au maximum les INTERFACES GRAPHIQUES !
Important : Une fois résolu, pensez à clore votre sujet en ajoutant [Résolu] devant le titre du 1er message, et un bref récapitulatif de la solution à la fin de celui-ci. Merci.

Hors ligne

#3 Le 14/04/2018, à 16:56

pingouinux

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

Bonjour,
Tu pourrais utiliser python, qui te permettrait de faire facilement ce que tu veux.

Hors ligne

#4 Le 14/04/2018, à 16:58

Brice Jeunieaux

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

Effectivement, actuellement Bash ne gère pas les tableaux multi-dimensionnels, mais effectivement je pourrais ruser en mettant en tableau le nom des autres tableaux, et j'ai très bien compris comment faire, mais disons que dans mon cas, le remplissage des tableaux doit se faire au sein d'une boucle for, je ne peux pas faire d'affectation manuelle, car les données que je dois mettre dans ce tableau varie, d'où l'obligation pour moi de l'automatisation par une boucle for... hmm

Hors ligne

#5 Le 14/04/2018, à 16:59

erresse

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

pingouinux a écrit :

Bonjour,
Tu pourrais utiliser python, qui te permettrait de faire facilement ce que tu veux.

+1! Il y a ça aussi. En python, tu as les listes et les tableaux, peut-être même les tableaux multidimensionnels...


Plus de 50 ans d'informatique, ça en fait des lignes de commandes en console, mais on n'avait pas le choix...
Excellente raison pour, aujourd'hui qu'on le peut, utiliser au maximum les INTERFACES GRAPHIQUES !
Important : Une fois résolu, pensez à clore votre sujet en ajoutant [Résolu] devant le titre du 1er message, et un bref récapitulatif de la solution à la fin de celui-ci. Merci.

Hors ligne

#6 Le 14/04/2018, à 16:59

Brice Jeunieaux

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

pingouinux a écrit :

Bonjour,
Tu pourrais utiliser python, qui te permettrait de faire facilement ce que tu veux.

C'est vrai, mais l'un des principes de ma BD est d'être gérée en Bash, donc, je ne veux qu'un seul langage, désolé... hmm

Hors ligne

#7 Le 14/04/2018, à 17:14

Watael

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

ne peux-tu insérer un séparateur différent de l'IFS entre les listes pour les distinguer ?

liste1=( {a..d} )
liste2=( {e..h} )
declare -A aAss
aAss["elem1"]="${liste1[@]}µ${liste2[@]}"

ou alors jouer sur l'indice du tableau associatif :

declare -A aAss
aAss["elem1µe1"]="{a..d}"
aAss["elem1µe2"]="{e..h}"

je persiste : il y a probablement une erreur de conception au départ du projet.


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

En ligne

#8 Le 14/04/2018, à 17:30

erresse

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

Brice Jeunieaux a écrit :

Effectivement, actuellement Bash ne gère pas les tableaux multi-dimensionnels, mais effectivement je pourrais ruser en mettant en tableau le nom des autres tableaux, et j'ai très bien compris comment faire, mais disons que dans mon cas, le remplissage des tableaux doit se faire au sein d'une boucle for, je ne peux pas faire d'affectation manuelle, car les données que je dois mettre dans ce tableau varie, d'où l'obligation pour moi de l'automatisation par une boucle for... hmm

Heuu... Je ne vois pas trop en quoi ça pose un problème que les tableaux contenant les éléments soient affectés dynamiquement ?!?
Peut-être peux-tu détailler ta phrase ou l'illustrer avec un exemple concret ?

Dernière modification par erresse (Le 14/04/2018, à 17:30)


Plus de 50 ans d'informatique, ça en fait des lignes de commandes en console, mais on n'avait pas le choix...
Excellente raison pour, aujourd'hui qu'on le peut, utiliser au maximum les INTERFACES GRAPHIQUES !
Important : Une fois résolu, pensez à clore votre sujet en ajoutant [Résolu] devant le titre du 1er message, et un bref récapitulatif de la solution à la fin de celui-ci. Merci.

Hors ligne

#9 Le 14/04/2018, à 17:45

Brice Jeunieaux

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

erresse a écrit :
Brice Jeunieaux a écrit :

Effectivement, actuellement Bash ne gère pas les tableaux multi-dimensionnels, mais effectivement je pourrais ruser en mettant en tableau le nom des autres tableaux, et j'ai très bien compris comment faire, mais disons que dans mon cas, le remplissage des tableaux doit se faire au sein d'une boucle for, je ne peux pas faire d'affectation manuelle, car les données que je dois mettre dans ce tableau varie, d'où l'obligation pour moi de l'automatisation par une boucle for... hmm

Heuu... Je ne vois pas trop en quoi ça pose un problème que les tableaux contenant les éléments soient affectés dynamiquement ?!?
Peut-être peux-tu détailler ta phrase ou l'illustrer avec un exemple concret ?

Prenons par exemple ce code :

nbPagesBD=3 ;

declare -A numPages ;

for (( a=1 ; a<=$nbPagesBD ; a++ )) do					#Pour chaque page l'on va afficher leurs données
	
	varTemp="Page$a"						#Création d'une variable temporaire contenant le nom de la clé
	echo $varTemp							#d'un élément. Par la suite on va affecter une valeur aux éléments
									#contenant cette clé "évolutive".
									
	numPages["$varTemp"]="$a $a $a" ;				#Affectation de valeurs bidon
	
done

Disons que grâce à la boucle for, je peux, pour un nombre qui varie que l'on va appeler "Alpha", remplir un certain nombre de tableaux de plusieurs variables (le nombre de tableaux à remplir étant "Alpha").

Donc si "Alpha" vaut quatre, j'aurais :

for (( a=1 ; a<=$Alpha ; a++ )) do					#Pour chaque page l'on va afficher leurs données
	
	varTemp="Page$a"						#Création d'une variable temporaire contenant le nom de la clé
	echo $varTemp							#d'un élément. Par la suite on va affecter une valeur aux éléments
									#contenant cette clé "évolutive".
									
	numPages["$varTemp"]="$a $a $a" ;				#Affectation de valeurs bidon
	
done

Sauf que comme tu le vois, cette ligne ci-dessous fonctionnera correctement mais le problème est que ça va stocker une unique chaîne de caractères (car présence de guillemets et non de parenthèses qui font que c'est une chaîne qui est stockée) :

numPages["$varTemp"]="$a $a $a" ;				#Affectation de valeurs bidon

Hors ligne

#10 Le 14/04/2018, à 17:56

Brice Jeunieaux

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

Watael a écrit :

ne peux-tu insérer un séparateur différent de l'IFS entre les listes pour les distinguer ?

liste1=( {a..d} )
liste2=( {e..h} )
declare -A aAss
aAss["elem1"]="${liste1[@]}µ${liste2[@]}"

ou alors jouer sur l'indice du tableau associatif :

declare -A aAss
aAss["elem1µe1"]="{a..d}"
aAss["elem1µe2"]="{e..h}"

je persiste : il y a probablement une erreur de conception au départ du projet.


Ta solution avec une histoire de séparateur m'intéresse fortement, car elle pourrait être une alternative intéressante au fait que Bash ne gère pas les tableaux multi-dimensionnels directement, mais je ne m'y connais vraiment pas avec tout ça, les séparateurs, IFS, etc...

Je sais traiter une ligne avec grep et cut, pour une ligne de données comme sur un fichier .cvs mais je ne vois pas trop de quoi tu parles.
Aurais-tu un cours sur le sujet ? (Désolé, j'ai vu ton message tard... sad )


EDIT : J'ai vu que tu as écrit tableau["element"]=" { } " avec des accolades.
Quel est le but de ces accolades, est-ce que ça permet de contrer la non-gestion des tableaux multi-dimensionnels de Bash ? Ça m'intrigue fortement...

Dernière modification par Brice Jeunieaux (Le 14/04/2018, à 18:03)

Hors ligne

#11 Le 14/04/2018, à 21:47

Watael

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

$ liste1=( {a..d} )
$ liste2=( {e..h} )
$ liste3=( {i..l} )
$ liste4=( {m..p} )
$ declare -A aAss=( ["1-1"]="${liste1[@]}" ["1-2"]="${liste2[@]}" ["2-1"]="${liste3[@]}" ["2-2"]="${liste4[@]}" )
$ echo "${aAss["2-1"]}"
i j k l

les accolades devraient développer {a..d} en a b c d, mais cela ne fonctionne pas pour les variables et les éléments d'un tableau. sad

Dernière modification par Watael (Le 14/04/2018, à 21:50)


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

En ligne

#12 Le 15/04/2018, à 11:19

erresse

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

C'est sans doute contraire à toutes les règles (surtout de Watael), mais comme ça, je pense que ça peut marcher...
1) Pour charger les informations dans les tableaux :

 user@user-mate:~$ for (( a=0; a<3; a++ )); do tb[$a]="tb$a"; for (( b=0; b<5; b++ )); do eval tb$a[$b]="\"elem $a,$b\""; done; done
 user@user-mate:~$ echo "${tb[@]}"
tb0 tb1 tb2
 user@user-mate:~$ echo "${tb0[@]}"
elem 0,0 elem 0,1 elem 0,2 elem 0,3 elem 0,4
 user@user-mate:~$ echo "${tb1[@]}"
elem 1,0 elem 1,1 elem 1,2 elem 1,3 elem 1,4
 user@user-mate:~$ echo "${tb2[@]}"
elem 2,0 elem 2,1 elem 2,2 elem 2,3 elem 2,4

2) Pour extraire les valeurs des tableaux :

tb1=("elem 1" "elem 2" "elem 3" "elem 4" "elem 5")
tb2=("arti 1" "arti 2" "arti 3" "arti 4" "arti 5")
idx=(tb1 tb2)
get(){
	eval echo "\${${idx[$1]}[$2]}"
}
for (( a=0; a<${#idx[@]}; a++ )); do
	eval c="\${#${idx[$a]}[@]}"
	for (( b=0; b<$c; b++ )); do
		eval echo "\${${idx[$a]}[$b]}"
	done
done
valeur=$(get 1 2)
echo "valeur=$valeur"

À toi de voir si tu peux adapter quelque chose à partir de ces codes... Tu peux toujours faire quelques essais dans ton terminal.


Plus de 50 ans d'informatique, ça en fait des lignes de commandes en console, mais on n'avait pas le choix...
Excellente raison pour, aujourd'hui qu'on le peut, utiliser au maximum les INTERFACES GRAPHIQUES !
Important : Une fois résolu, pensez à clore votre sujet en ajoutant [Résolu] devant le titre du 1er message, et un bref récapitulatif de la solution à la fin de celui-ci. Merci.

Hors ligne

#13 Le 17/04/2018, à 12:50

Brice Jeunieaux

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

Je fais un petit point juste pour dire que je n'ai pas abandonné la recherche d'une solution, je reste juste silencieux car toujours en train d'étudier vos propositions, je posterai si jamais je rencontrerai quelque chose de négatif/positif pour une solution adoptée.

De plus, je pense avoir vraiment besoin de eval, bien que la terre entière semble ne pas l'aimer pour beaucoup de cas d'utilisation.
Mes connaissances et mon expérience ne me permettent pas de déterminer à quel moment eval me causera du tort, et pour l'instant, je pense que dans mon cas d'utilisation, ça ferait ce que je demande, donc je pense me tourner vers cette solution. wink

Hors ligne

#14 Le 17/04/2018, à 13:38

erresse

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

Il ne faut pas se formaliser, si une instruction "eval" existe, c'est qu'elle a son utilité, quelque soit le point de vue de "la terre entière" ! tongue
Si, comme c'est apparemment le cas ici puisqu'on ne trouve pas de commandes/instructions pour le faire, il faut composer quelque chose et l'exécuter dynamiquement avec "eval", il n'y a pas de raison de s'en priver, chacun est responsable de ce qu'il développe pour son propre usage, non ?
Le risque en utilisant "eval", en fait, c'est que cette instruction exécute une commande contenue dans une variable, et que si cette variable contient une commande risquée, elle va s'exécuter sans plus de contrôles...
Rien ne t'empêche de t'assurer que la commande qu'exécute "eval" est saine et correspond à ce que tu veux faire avant de lancer son exécution, voilà tout.
La solution que je t'ai proposée use et abuse de "eval", mais elle a le mérite de fonctionner et de faire ce qu'on en attend. Ce qui, à mes yeux, justifie tout à fait d'utiliser les commandes et instructions à ma disposition pour arriver à mes fins !
big_smile


Plus de 50 ans d'informatique, ça en fait des lignes de commandes en console, mais on n'avait pas le choix...
Excellente raison pour, aujourd'hui qu'on le peut, utiliser au maximum les INTERFACES GRAPHIQUES !
Important : Une fois résolu, pensez à clore votre sujet en ajoutant [Résolu] devant le titre du 1er message, et un bref récapitulatif de la solution à la fin de celui-ci. Merci.

Hors ligne

#15 Le 17/04/2018, à 15:22

pingouinux

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

Tout à fait d'accord avec erresse #14. De même, lorsque tu exécutes un script, il est préférable (c'est un euphémisme) d'être certain de son contenu.

Hors ligne

#16 Le 17/04/2018, à 17:27

Watael

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

je vous dis qu'le picrate est bouchonné !
la bouteille a été débouchée de travers. Alors, forcément, maintenant, c'est imbuvable. sad
et vous n'allez pas le servir à table avec une passoire ?!


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

En ligne

#17 Le 15/05/2018, à 17:53

Brice Jeunieaux

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

Bonjour / bonsoir ,

tout d'abord, non je ne suis pas mort, je n'ai pas non plus enterré le projet ni ce sujet, j'y réfléchissais et j'ai également pris une certaine pause pour me reformer aux tableaux associatifs en Bash, réponse source de Watael sur ce sujet là ou l'ancien (j'en avais bien besoin, d'une pause de formation tongue).

Cela a porté ses fruits puisqu'aujourd'hui, mon problème initial est résolu, je n'ai plus besoin d'avoir des noms de variables manipulés dans des boucles, et j'ai réussi tout simplement en utilisant (attention, suspense pseudo-insoutenable)...  les tableaux associatifs ! cool ( Tadaaa ?! )


Donc, bien que je compte passer ce sujet en Résolu d'ici peu le temps que les potentiels participants intéressés voient la réponse, et bien la voici :

Mon tableau associatif contient des clefs qui concrètement sont : "Page1,Ligne5" (par exemple).
Le '1' est en fait une variable $a qui est le numéro de la "page" (pour rappel, j'affiche les lignes de données 15 par 15, 15 lignes pour une page affichée.
Le '5' est en fait le numéro de la ligne pour cette page.

Du coup, en manipulant ces variables $a et $b au sein de boucles, je peux créer des clés contenants ces variables, qui seront associés à certaines lignes de données en fonctions de celles-ci.

Exemple :

echo ${tab1[Page2,LD27]}

renvoie une certaine ligne de donnée (ou un morceau avec la commande cut).


Conclusion : Grâce à l'utilisation des tableaux associatifs, je n'ai pas besoin d'utiliser 'eval', pour le plus grand bonheur de Watael roll (je taquine...).
Merci à ceux qui m'ont aidé, et je passerai ce sujet en Résolu très probablement demain dans la journée !

Hors ligne

#18 Le 19/05/2018, à 15:24

LeoMajor

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

bonjour,

tu peux utiliser source aussi. tu auras une abstraction et une modélisation plus élevée, à l'arrivée.

~$ OBJ.CREATE clients persons_class
1
~$ __clients.init
1
~$ __clients.count 
0
~$ __clients.add "intermarche##25 rue de pierre Curie#34#tours"
1
~$ __clients.add "auchan#jardin#560, avenue des marchands#29#Brest"
1
~$ __clients.add "bricomarche#jardin#5, rue marie Curie#25#doubs"
1
__clients.add "intermarche##75, rue marie Delatour#75#Paris"
1
__clients.add "casino#alimentation#1, place de l'eglise#60#ville-basse"
1
__clients.add "leclerc#boulangerie##84#carpentras"
1
~$ __clients.count 
6
~$ __clients.get 2
--Personnes[2]
                  id:	d31b0
         Nom/Societe:	auchan
     Prenom/Rubrique:	jardin
             adresse:	560, avenue des marchands
         code-postal:	29
               ville:	Brest
~$ __clients.getall
--Personnes[1]
                  id:	c9b9e
         Nom/Societe:	intermarche
     Prenom/Rubrique:	
             adresse:	25 rue de pierre Curie
         code-postal:	34
               ville:	tours
--Personnes[2]
                  id:	d31b0
         Nom/Societe:	auchan
     Prenom/Rubrique:	jardin
             adresse:	560, avenue des marchands
         code-postal:	29
               ville:	Brest
--Personnes[3]
                  id:	2bbec
         Nom/Societe:	bricomarche
     Prenom/Rubrique:	jardin
             adresse:	5, rue marie Curie
         code-postal:	25
               ville:	doubs
--Personnes[4]
                  id:	93b62
         Nom/Societe:	intermarche
     Prenom/Rubrique:	
             adresse:	75, rue marie Delatour
         code-postal:	75
               ville:	Paris
--Personnes[5]
                  id:	1e3e9
         Nom/Societe:	casino
     Prenom/Rubrique:	alimentation
             adresse:	1, place de l'eglise
         code-postal:	60
               ville:	ville-basse
--Personnes[6]
                  id:	36c26
         Nom/Societe:	leclerc
     Prenom/Rubrique:	boulangerie
             adresse:	
         code-postal:	84
               ville:	carpentras

~$ __clients.search 'intermarche' all 
Personnes[4]Nom/Societe<2>:intermarche
Personnes[1]Nom/Societe<2>:intermarche

~$ __clients.search 'intermarche' key
4,2
1,2

~$ __clients.search 'intermarche' k²
Personnes[4]
Personnes[1]

 ~$ __clients.search '.*marie.*' solve
--Personnes[3]
                  id:	2bbec
         Nom/Societe:	bricomarche
     Prenom/Rubrique:	jardin
             adresse:	5, rue marie Curie
         code-postal:	25
               ville:	doubs
--Personnes[4]
                  id:	93b62
         Nom/Societe:	intermarche
     Prenom/Rubrique:	
             adresse:	75, rue marie Delatour
         code-postal:	75
               ville:	Paris

~$ if [ $(__clients.count) -gt 3 ]; then echo "il y a au moins 3 enregistrements: $(__clients.count) exactement"; fi 
il y a au moins 3 enregistrements: 6 exactement

Hors ligne

#19 Le 19/05/2018, à 19:51

Brice Jeunieaux

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

LeoMajor a écrit :

bonjour,

tu peux utiliser source aussi. tu auras une abstraction et une modélisation plus élevée, à l'arrivée.

[  . . .  ]

Bonsoir,

ta réponse m'intrigue beaucoup, je ne comprends pas tout ce charabia, car je ne connais pas ce fameux "source", mais ça m'intéresse.
Peux-tu m'en dire plus ?

Dernière modification par Brice Jeunieaux (Le 19/05/2018, à 19:51)

Hors ligne

#20 Le 20/05/2018, à 18:20

LeoMajor

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

source command
dot command

.  script
ou équivalent 
source script

pour faire court
~/.bashrc

. "$HOME/.bashobj/obj"

~/scripts/bash_libobj   

function OBJ {
source <(sed "s/self/$name/g" "$HOME/scripts/persons_class")

"$HOME/scripts/persons_class"

function __self.init {
unset __self__ 
declare -Ag __self__='(["0,1"]="0")'
printf "%d\n" 1
}
...

Hors ligne

#21 Le 21/05/2018, à 19:25

Brice Jeunieaux

Re : [Résolu] Comment affecter une liste à un élément de tableau ?

LeoMajor a écrit :

Ok, merci beaucoup pour tes réponses, ça m'intéresse pas mal, je vais étudier ça dans mon script.

Hors ligne