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 16/11/2017, à 10:41

Arbiel

[Résolu] Initialisation d'un tableau associatif

Bonjour à tous

Le script ci-dessous, qui essaie de mémoriser la position, ligne et colonne, de caractères tous différents et contenus dans quelques lignes, ne fonctionne pas, comme le montre l'exécution que j'en fais
Le script

#! /bin/bash
		function positions {
			cat << EOF
abcdef
ghijklmnopqsrt
uvwxyz
EOF
		}
		function dico {
			l=0
			positions | while read ligne;
				do
				l=$((l+1));
				i=0
# je n'ai pas réussi à utiliser for (( a, b, c)) avec c du style c++
				 while [[ $((${#ligne}-${i})) -gt 0 ]];
					do
					j=$((${i}+1));
# je n'ai pas réussi à utiliser printf pour avoir j sur deux caractères en toutes circonstances
						case "${#j}" in
							1) rg="0${j}";;
							2) rg="${j}";;
						esac;
################# c'est ici que j'essaie de mémoriser la position des lettres ###################
						Tab["${ligne:${i}:1}"]="l${l}c${rg}";
						echo "Le caractère ${!Tab["${ligne:${i}:1}"]} est en position ${Tab["${ligne:${i}:1}"]}";
################################################################################################
						i=$((${i}+1));
					done ;
				done;
		echo "${Tab[*]}"
		}
	declare -A Tab
	dico
	echo ${Tab[@]};
	echo ${!Tab[@]}

L'exécution

remi@remi-Vostro-3550:~$ ~/Bureau/test
Le caractère  est en position l1c01
Le caractère  est en position l1c02
Le caractère  est en position l1c03
Le caractère  est en position l1c04
Le caractère  est en position l1c05
Le caractère  est en position l1c06
Le caractère  est en position l2c01
Le caractère  est en position l2c02
Le caractère  est en position l2c03
Le caractère  est en position l2c04
Le caractère  est en position l2c05
Le caractère  est en position l2c06
Le caractère  est en position l2c07
Le caractère  est en position l2c08
Le caractère  est en position l2c09
Le caractère  est en position l2c10
Le caractère  est en position l2c11
Le caractère  est en position l2c12
Le caractère  est en position l2c13
Le caractère  est en position l2c14
Le caractère  est en position l3c01
Le caractère  est en position l3c02
Le caractère  est en position l3c03
Le caractère  est en position l3c04
Le caractère  est en position l3c05
Le caractère  est en position l3c06



remi@remi-Vostro-3550:~$ 

Merci d'avance à quiconque pourra me mettre sur la voie de la solution.

Arbiel

Dernière modification par Arbiel (Le 17/11/2017, à 23:46)


Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04
Abandon d'azerty au profit de bépo, de google au profit de Lilo et de la messagerie électronique violable au profit de Protonmail, une messagerie chiffrée de poste de travail à poste de travail.

Hors ligne

#2 Le 16/11/2017, à 12:49

pingouinux

Re : [Résolu] Initialisation d'un tableau associatif

Bonjour,
Voici une version simplifiée :

#! /bin/bash
function positions { 
   cat << EOF
abcdef
ghijklmnopqsrt
uvwxyz
EOF
}

function dico {
   l=0
   while read ligne;
   do
      ((l++));
      j=0
      while read -n1 car
      do
         [ "$car" ] || break
         printf -v rg "%02d" $((++j))
         Tab["$car"]="l${l}c${rg}";
      done <<<"$ligne"
   done < <(positions);
}

declare -A Tab
dico
echo ${Tab[@]};
echo ${!Tab[@]}

for car in ${!Tab[@]}
do
   echo "Le caractère $car est en position ${Tab["$car"]}";
done

Édité : Simplification

Dernière modification par pingouinux (Le 16/11/2017, à 13:14)

Hors ligne

#3 Le 16/11/2017, à 14:39

erresse

Re : [Résolu] Initialisation d'un tableau associatif

Salut,
pingouinux, pourquoi y a-t-il une inversion entre l2c13 et l2c12 ???

l1c01 l1c02 l1c03 l1c04 l1c05 l1c06 l2c01 l2c02 l2c03 l2c04 l2c05 l2c06 l2c07 l2c08 l2c09 l2c10 l2c11 l2c13 l2c12 l2c14 l3c01 l3c02 l3c03 l3c04 l3c05 l3c06
a b c d e f g h i j k l m n o p q r s t u v w x y z
Le caractère a est en position l1c01
Le caractère b est en position l1c02
Le caractère c est en position l1c03
Le caractère d est en position l1c04
Le caractère e est en position l1c05
Le caractère f est en position l1c06
Le caractère g est en position l2c01
Le caractère h est en position l2c02
Le caractère i est en position l2c03
Le caractère j est en position l2c04
Le caractère k est en position l2c05
Le caractère l est en position l2c06
Le caractère m est en position l2c07
Le caractère n est en position l2c08
Le caractère o est en position l2c09
Le caractère p est en position l2c10
Le caractère q est en position l2c11
Le caractère r est en position l2c13
Le caractère s est en position l2c12
Le caractère t est en position l2c14
Le caractère u est en position l3c01
Le caractère v est en position l3c02
Le caractère w est en position l3c03
Le caractère x est en position l3c04
Le caractère y est en position l3c05
Le caractère z est en position l3c06

Quelque chose m'échappe, mais ce script donne quand même un résultat encourageant...
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

#4 Le 16/11/2017, à 15:02

Arbiel

Re : [Résolu] Initialisation d'un tableau associatif

Merci beaucoup pour votre aide.

J'apprécie le script simplifié, dont je comprends bien le fonctionnement et que je vais utiliser, mais qui me laisse perplexe sur les raisons pour lesquelles mon script ne fonctionne pas.

Je ne comprends bien la formulation

done < <(positions);

À quoi correspond l'espace entre les deux < ? pourquoi pas "<<" puisque (positons) me semble un fichier au même titre que "cat EOF" ?

Entre temps. j'ai construit une variable dans laquelle je stocke des commandes du style Tab["a"]="l1c01" et que j'exécute ensuite par la commande eval. Je revenais le dire lorsque j'ai vu vos interventions.

J'avais auparavant remplacé

Tab["${ligne:${i}:1}"]="l${l}c${rg}";

par

lettre="${ligne:${i}:1}"
Tab["${lettre}"]="l${l}c${rg}";

mais sans résultat positif.

@erresse
la relecture d'un tableau associatif ne redonne pas forcément les éléments dans l'ordre dans lequel ils ont été créés, contrairement je pense. à un tableau indexé, qui les redonne dans l'ordre de l'index.

Dernière modification par Arbiel (Le 16/11/2017, à 15:12)


Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04
Abandon d'azerty au profit de bépo, de google au profit de Lilo et de la messagerie électronique violable au profit de Protonmail, une messagerie chiffrée de poste de travail à poste de travail.

Hors ligne

#5 Le 16/11/2017, à 15:25

erresse

Re : [Résolu] Initialisation d'un tableau associatif

Je viens de m'apercevoir que l'ordre des caractères des données à charger est lui-même inversé pour le "s" et le "r", donc en sortant les résultats dans l'ordre alphabétique, il est normal que les coordonnées le soient aussi pour rétablir "r" et "s"...
Pour le "done > >(positions)", je présume que c'est parce-que "positions" est une fonction du script et non un fichier externe, non ?


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 16/11/2017, à 17:47

pingouinux

Re : [Résolu] Initialisation d'un tableau associatif

done < <(positions);

<(positions) est la sortie standard de la fonction positions
Le premier < veut dire que la sortie ci-dessus est prise comme entrée standard de la boucle.

Avec la méthode d'Arbiel en #1

			positions | while read ligne;

la boucle while était exécutée dans un sous-shell, et on ne récupérait pas le tableau Tab en sortie de boucle.

Hors ligne

#7 Le 16/11/2017, à 20:02

pingouinux

Re : [Résolu] Initialisation d'un tableau associatif

python (ici python3) est bien adapté pour ce genre de manip. Dans un cas comme dans l'autre, si un caractère apparaît plusieurs fois, seule la dernière occurrence sera prise en compte.

#!/usr/bin/env python3

s='''abcdef
ghijklmnopqsrt
uvwxyz'''

def dico(s):
   Tab={}; j=1; i=0
   for car in s:
      if car=='\n': j+=1; i=0; continue
      i+=1
      Tab[car]="l%dc%02d"%(j,i)
   return Tab

Tab=dico(s)
for car in sorted(Tab): print("Le caractère %s est en position %s"%(car,Tab[car]))

Hors ligne

#8 Le 16/11/2017, à 22:14

Arbiel

Re : [Résolu] Initialisation d'un tableau associatif

Bonsoir

Le petit bout de code que j'ai eu bien des difficultés à mettre au point est destiné à intégrer un script plus important, et je ne connais absolument pas python. J'ai commencé à m'y intéresser il y a peu, mais je n'ai plus le temps de poursuivre.

J'ai repris le manuel bash pour comprendre la gestion des variables par les environnements. Si je le comprends bien, pour récupérer les valeurs du tableau, j'aurais dû le déclarer avec l'option -x.

Dans le sous-shell, l'instruction d'affectation Tab["${car}"]="valeur" concerne un tableau différent de celui que j'ai déclaré, et non déclaré dans le contexte d'exécution. Et bash ne donne pas d'erreur même si Tab n'a pas été préalablement explicitement déclaré comme tableau associatif. C'est un peu dommage, mais même si bash m'avait averti d'une erreur à ce niveau là, je ne suis pas certain que j'aurais compris.

Enfin l'écriture a < < b fonctionne comme le pipeline b | a. C'est en quelque sorte un pipeline écrit à l'envers.

Pour ce qui concerne l'inversion de r et de s, je n'avais pas vu mon erreur.

Merci encore.

Arbiel


Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04
Abandon d'azerty au profit de bépo, de google au profit de Lilo et de la messagerie électronique violable au profit de Protonmail, une messagerie chiffrée de poste de travail à poste de travail.

Hors ligne

#9 Le 17/11/2017, à 06:03

Watael

Re : [Résolu] Initialisation d'un tableau associatif

salut,

encore plus simple

genTxt()
{
    printf '%s\n' "abcdef" "ghijklmnopqrst" "uvwxyz"
}

declare -A coordonnees

while read line
do
    ((++nl))
    for ((i=0;i<${#line};i++))
    do
        coordonnees[${line:$i:1}]="l${nl}p$i"
    done
done < <(genTxt)

for i in ${!coordonnees[@]}
do
    echo "le caractère $i est à ${coordonnees[$i]}"
done

pour que le pipe fonctionne (que les variables qui y sont définies dans la partie droite soient disponibbles après), en bash, dans un script uniquement (pour faire simple), il est possible de configurer lastpipe avec shopt.

Dernière modification par Watael (Le 17/11/2017, à 06:04)


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

Hors ligne

#10 Le 17/11/2017, à 12:23

Arbiel

Re : [Résolu] Initialisation d'un tableau associatif

Bonjour

Effectivement

manuel bash a écrit :

This builtin allows you to change additional shell optional behavior.

shopt
………
lastpipe

    If set, and job control is not active, the shell runs the last command of a pipeline not executed in the background in the current shell environment.

Je dois humblement avoué que je n'ai jamais eu le courage de lire l'intégralité de la commande shopt, dont la présentation dans le manuel est, il faut bien le dire, mais ce n'est pas une excuse, assez rébarbative.

Je te remercie pour ton intervention dans laquelle je retiens surtout l'utilisation de printf au lieu de cat <<< EOF.

Pour ce qui concerne le traitement de chaque ligne, la lecture avec -n1 m'avait un peu surpris, surtout par le fait que, apparemment, elle renvoie un caractère vide en fin de ligne (mais pas la valeur false ? - je n'ai pas relu le manuel à son sujet). Elle présente, à mes yeux, l'avantage d'une lecture un peu plus aisée dans la mesure où "${#ligne} est très concis.

Merci encore

Arbiel


Arbiel Perlacremaz
LDLC Aurore NK3S-8-S4 Ubuntu 20.04
Abandon d'azerty au profit de bépo, de google au profit de Lilo et de la messagerie électronique violable au profit de Protonmail, une messagerie chiffrée de poste de travail à poste de travail.

Hors ligne