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 23/03/2018, à 20:03

Nony80

Script BASH, tri par sélection dans tableau

Bonjour à tous,

Dans le cadre de mon apprentissage de bash (une quinzaine de jours actuellement), je dois répondre à un exercice simple sur le papier.

L'objectif est d'intégrer des nombres entiers dans un tableau.
Puis d'en ressortir la note minimale et la note maximale.
En indice, on nous dit d'utiliser le tri par sélection, de cette façon la note minimale et maximale seront aux extrémités.

Donc j'ai commencé mon script de cette façon, j'ai mis les commentaires pour vous montrer ce que j'ai fait et ce que j'aimerais faire.
Ça sera plus parlant je pense.

#!/bin/bash

# script permettant d'entrer des valeurs dans un tableau et d'en ressortir :
# la note minimale
# la note maximale

# On demande à saisir les notes à intégrer à notre tableau s'appellant tableaunote
read -p "Saisir un tableau d'entrier : " -a tableaunote

# on crée la variable monTableau contenant toutes les valeurs du tableau 
# on crée la variable totalValeur contenant le nombre d'éléments présents dans le tableau
monTableau=${tableaunote[*]}
totalValeur=${#tableaunote[*]}

# Tant que le nombre d'éléments est supérieur à 0
while [ $totalValeur -gt 0 ]; do

	# Pour chaque éléments de mon tableau
	# Si le premier élément est plus grand que tous les autres éléments du tableau, alors
	# on place le premier élément en tant que dernier élément
	# et on décrément de 1 le nombre d'élément total afin de faire la même analyse au tout suivant entre $1 et les autres éléments sauf le dernier élément
	# sinon si $1 est plus petit qu'un des autres éléments du tableau alors on passe à l'élément suivant
	
	for element in $monTableau; do
		if 
		totalValeur=$((totalValeur-1))
	done
done

Comme vous voyez, je me suis arrêter au while réellement, tout le reste j'en parle en commentaire mais je ne suis même pas convaincu que c'est possible de cette façon.
Par contre SVP, ne m'envoyez pas des liens autres, car j'ai quasiment tout parcouru, j'ai vu des exemples mais non commentés et incompréhensibles à mon niveau.

Pouvez-vous m'aider en m'expliquant ?

Hors ligne

#2 Le 23/03/2018, à 20:19

Watael

Re : Script BASH, tri par sélection dans tableau

salut,

on reprend depuis le début :
tu as rempli un sac opaque avec un certain nombre de cailloux.
comment fais-tu pour trouver le plus gros ?

ne parlons pas de programmation pour l'instant.


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

Hors ligne

#3 Le 23/03/2018, à 21:06

Nony80

Re : Script BASH, tri par sélection dans tableau

Salut Watael,

Je prend un cailloux et je le compare à un autre.
Si le premier cailloux est plus gros, je compare avec un autre cailloux.
Si le premier cailloux est plus petit, je garde le deuxième cailloux et le compare avec d'autres cailloux hormis le premier.

Hors ligne

#4 Le 23/03/2018, à 21:27

lynn

Re : Script BASH, tri par sélection dans tableau

Nony80 a écrit :

le tri par sélection

Le tri ou la sélection! Le tri est nécessairement une sélection...


«C'est pas parce qu'ils sont nombreux à avoir tort qu'ils ont raison!»

Coluche

Hors ligne

#5 Le 23/03/2018, à 21:28

Watael

Re : Script BASH, tri par sélection dans tableau

c'est ça.

sommairement :
pour un_caillou dans la sac,
.   si il y a un plus_gros_caillou
.   alors
.      si un_caillou est-plus-gros-que plus_gros_caillou
.      alors
.         plus_gros_caillou=un_caillou
.      finSi
.   autrement
.      plus_gros_caillou=un_caillou
.   finSi
finPour


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

Hors ligne

#6 Le 23/03/2018, à 21:58

Nony80

Re : Script BASH, tri par sélection dans tableau

Je comprend ce que tu veux dire mais il me manque des connaissances pour le mettre en place.
Je bloque à :
si il y a un plus_gros_caillou # Ici je ne vois pas comment savoir qui est le plus_gros_caillou
si un_caillou est-plus-gros-que plus_gros_caillou # là encore je ne vois pas comment faire,
...et malheureusement c'est pareil pour le reste.

Dans ce que tu as marqué, je ne vois pas à quel moment les arguments changent de places. :-/

Hors ligne

#7 Le 23/03/2018, à 22:35

pingouinux

Re : Script BASH, tri par sélection dans tableau

Bonsoir,
Si tu n'as besoin que des valeurs extrêmes, il est inutile de trier tout le tableau.

vmin=premier_element
vmax=premier_element
Parcourir le tableau à partir du deuxième élément
   Si element<vmin : Alors vmin=element
   Si element>vmax : Alors vmax=element

Hors ligne

#8 Le 23/03/2018, à 22:39

Watael

Re : Script BASH, tri par sélection dans tableau

en effet, on ne trie pas le tableau : on retient l'élément qui correspond au critère.


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

Hors ligne

#9 Le 24/03/2018, à 00:11

Nony80

Re : Script BASH, tri par sélection dans tableau

pingouinux a écrit :

Bonsoir,
Si tu n'as besoin que des valeurs extrêmes, il est inutile de trier tout le tableau.

vmin=premier_element
vmax=premier_element
Parcourir le tableau à partir du deuxième élément
   Si element<vmin : Alors vmin=element
   Si element>vmax : Alors vmax=element

Bonsoir pingouinux,

Donc en gros c'est
if $1 < le reste (je ne sais pas comment le représenter)
alors vmin = $1
echo minimal = $1
elif $1 > le reste (je ne sais pas dire non plus)
alors vmax = $1
echo maximal

J'ai un peu de mal à saisir avec ce code comment on peut ressortir le min et max.

Hors ligne

#10 Le 24/03/2018, à 01:11

Watael

Re : Script BASH, tri par sélection dans tableau

il faut itérer (énumérer) les éléments du tableau dans un boucle for :

pour item dans liste...

cf. help for

tu dois revoir la syntaxe de if.
cf. help if

Attention!
dans le contexte de la commande test, < est un faux-ami (on s'en sert dans du pseudo-code pour faire simple. tu verras plus tard que dans le contexte d'une Évaluation arithmétique, par contre, c'est correct tongue),
il compare exclusivement des chaînes alphanumériques (du texte), pas des nombres.
cf. help test

pour te faire la main avec les commandes et la syntaxe du shell, tu devrais les expérimenter dans des projets de plus petite importance : faire des tests simples, boucler sur des listes, élaborer des conditions plus complexes...

il faut expérimenter dans la console, n'essaie pas d'écrire un script si tu ne maîtrises pas un minimum les commandes et leur syntaxe.

Dernière modification par Watael (Le 24/03/2018, à 01:17)


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

Hors ligne

#11 Le 24/03/2018, à 02:15

Nony80

Re : Script BASH, tri par sélection dans tableau

Je comprend Watael, malheureusement, on ne nous laisse pas le temps.
Je dois rendre ce script avant dimanche soir, en sachant que j'ai un module qui me demande du travail aussi (Mise en place d'un VPN pour une entreprise).
Je vais essayer de trouver.
Merci à vous pour votre aide.

Hors ligne

#12 Le 24/03/2018, à 13:20

kholo

Re : Script BASH, tri par sélection dans tableau

salut,
une autre façon :

IFS=$'\n' sorted=( $(sort -nr <<<"${unTableau[*]}") )

sort ; -n pour numérique ; -r pour reverse

#!/bin/bash
desElements="13 5 45 12 56 32 87 44 1"
IFS=' ' unTableau=( $desElements )

echo "tous les élements du tableau"
for i in ${unTableau[@]}
do
	echo "-> $i"
done
echo "*************************************"
echo "traitement :"
# LA LIGNE EST ICI
IFS=$'\n' sorted=( $(sort -nr <<<"${unTableau[*]}") )
echo "*************************************
tous les éléments dans l'ordre décroissants"
for i in ${sorted[@]}
do
	echo "-> $i"
done
echo "*************************************"
echo "le plus grand est le premier élément : ${sorted[0]}"

exit 0

Hors ligne

#13 Le 24/03/2018, à 16:41

erresse

Re : Script BASH, tri par sélection dans tableau

Nony80 a écrit :

Donc en gros c'est
if $1 < le reste (je ne sais pas comment le représenter)
alors vmin = $1
echo minimal = $1
elif $1 > le reste (je ne sais pas dire non plus)
alors vmax = $1
echo maximal

J'ai un peu de mal à saisir avec ce code comment on peut ressortir le min et max.

Bonjour Nony80,
Tu as omis un point primordial dans la séquence que t'a indiquée pingouinux :
vmin=premier_element
vmax=premier_element
Il s'agit du chargement de la valeur initiale des variables "vmin" et "vmax".
Une fois ces valeurs initialisées, on ne fait de comparaison que deux à deux, on ne connaît évidemment pas la valeur de la totalité des éléments à un moment T, seulement celles de la valeur courante des variables "vmin" et "vmax", comparées à chaque élément du tableau au cours de la boucle.
Chaque fois que l'élément du tableau est inférieur à "vmin", on remplace la valeur de "vmin" par celle de l'élément du tableau.
Chaque fois que l'élément du tableau est supérieur à "vmax", on remplace la valeur de "vmax" par celle de l'élément du tableau.
À la fin de boucle, on aura forcément la plus petite valeur contenue dans le tableau dans "vmin" et la plus grande dans "vmax".
C'est aussi simple que ça...


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

#14 Le 24/03/2018, à 16:58

Watael

Re : Script BASH, tri par sélection dans tableau

read min max < <(printf '%s\n' "${array[@]}" | sort -n | sed -n '1h;${H;g;s/\n/ /p}')

?

big_smile


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

Hors ligne

#15 Le 24/03/2018, à 17:43

erresse

Re : Script BASH, tri par sélection dans tableau

C'est un  fait, il y a mille façon de faire pour obtenir le même résultat, mais je pense que Nony80 qui essaie de programmer en bash depuis une quinzaine de jours a surtout besoin de comprendre le fonctionnement pas à pas des instructions "de base" pour le moment.
Une commande telle que tu la proposes est certainement très efficace, mais pour le moins hermétique à tout profane qui n'a pas déjà absorbé 10 tomes de documentation sur le shell et le bash, ne crois-tu pas ?
(D'ailleurs, c'était bien ta démarche initiale, avec ton sac de cailloux. On se demande où il est passé dans cette version).


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

#16 Le 24/03/2018, à 19:20

Watael

Re : Script BASH, tri par sélection dans tableau

neutral
je faisais écho à la réponse de Kholo.

« c'est lui qu'a commencé ! »


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

Hors ligne

#17 Le 25/03/2018, à 02:08

Nony80

Re : Script BASH, tri par sélection dans tableau

Salut les gars,

Merci d'avoir continué le topic.
@kholo : ta solution est certainement très bonne mais le temps que je comprenne tous les détails du script, je serais passé à autre chose, je crois. ^^
@ Watael : c'est un beau oneline et je kifferais savoir faire ça en une ligne. smile
@erresse : merci pour ton explication sur mes doutes, je pense avoir compris du coup, en faite c'est logique en ayant l'explication devant mes yeux.
Je confond boucle et condition, ce qui est assez bête au finale...

Donc je me lance avec tes explications (pas encore testé sur la machine) :

#!/bin/bash

# script permettant d'entrer des valeurs dans un tableau et d'en ressortir :
# la note minimale
# la note maximale

# On demande à saisir les notes à intégrer à notre tableau s'appellant tableaunote
read -p "Saisir un tableau d'entrée : " -a tableaunote

# on crée la variable monTableau contenant toutes les valeurs du tableau 
# on crée la variable totalValeur contenant le nombre d'éléments présents dans le tableau
monTableau=${tableaunote[*]}


vmin=${tableaunote[0]}
vmax=${tableaunote[0]}


for element in $monTableau; do
	if [ $vmin -gt $element ]; then
		vmin=$element
	elif [ $vmax -lt $element ]; then
		vmax=$element
	fi
done

echo "Note minimale" = $vmin
echo "Note maximale" = $vmax

^

Edit : je viens de tester et ça fonctionne. Merci beaucoup, j'ai mis du temps quand même à le mettre en place. Mais je suis content. smile

Dernière modification par Nony80 (Le 25/03/2018, à 04:02)

Hors ligne

#18 Le 25/03/2018, à 04:17

Watael

Re : Script BASH, tri par sélection dans tableau

for element in "${tableauNote[@]}"

la variable "plate" monTableau (qui n'est d'ailleurs plus un tableau) ne sert à rien.

Dernière modification par Watael (Le 25/03/2018, à 04:18)


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

Hors ligne

#19 Le 25/03/2018, à 07:27

pingouinux

Re : Script BASH, tri par sélection dans tableau

Watael #18 a écrit :

la variable "plate" monTableau (qui n'est d'ailleurs plus un tableau) ne sert à rien.

En fait, "$monTableau" est le premier élément du tableau.

Hors ligne

#20 Le 25/03/2018, à 12:39

kholo

Re : Script BASH, tri par sélection dans tableau

@Nony80
c'est pas si compliqué que ça
ça repose juste sur les tableaux
et comme tu dois être en train d'apprendre à les gérer
voilà quelques trucs simples.

le premier truc que veut savoir un newbee est comment créer un tableau :

desElements="13 12 26 3 8 45 65"

pour le moment desElements est une chaîne alphanumérique
pour en faire un tableau :

unTableau=( $desElements )

Mais pour être certain que le séparateur est l'espace

IFS=' '

pour que le IFS= ne soit pris QUE pour la ligne : on le met sur la ligne sans séparateur ";"

IFS=' ' unTableau=( $desElements )

NB : $'\n' pour le saut de ligne
pour accèder à tous les éléments on utilise un for sur un tableau NON quotté :

for i in ${unTableau[@]}
do
    echo "la valeur est $i"
done

ou par son index :

for ((i=0 ; i<${#unTableau[@]} ; i++))
do
   echo "la valeur est ${unTableau[$i]} "
done

explication de la ligne que j'ai choisi :

IFS=$'\n' sorted=( $(sort -nr <<<"${unTableau[*]}") )

tous les éléments d'un tableau unTableau (en texte bout à bout)

"${unTableau[*]}"

est envoyé à

<<<

sort et rangé dans l'ordre numérique inverse

sort -nr 

le $() pour exécuter ça à part

$(sort -nr <<<"${unTableau[*]}")

ici les valeurs sont rangée dans l'ordre inverse
mais la sortie de ce code est un ensemble de lignes séparées par des sauts de lignes
donc on recrée un tableau avec le IFS déclaré pour prendre le saut de ligne comme séparateur

IFS=$'\n' ... ( $(du code ici) )

et on met le tout dans une variable sorted qui est un tableau

IFS=$'\n' sorted=( $(du code ici) )

voila...

Hors ligne

#21 Le 25/03/2018, à 12:53

Watael

Re : Script BASH, tri par sélection dans tableau

En fait, "$monTableau" est le premier élément du tableau.

monTableau=${tableaunote[*]}

ici, monTableau reprend, dans une variable "plate", le contenu ([\*], et non [0]) de tableaunote.


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

Hors ligne

#22 Le 25/03/2018, à 13:16

pingouinux

Re : Script BASH, tri par sélection dans tableau

@Watael :
Effectivement, j'ai un peu mélangé les variables monTableau et tableaunote.
Je voulais juste dire

$ tablo=( aaa bbb ccc ddd )

$ echo $tablo
aaa

mais cette remarque était hors de propos.

Hors ligne

#23 Le 25/03/2018, à 13:20

Watael

Re : Script BASH, tri par sélection dans tableau

effectivement, $tableaunote = ${tableaunote[0]}


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

Hors ligne

#24 Le 25/03/2018, à 13:53

Nony80

Re : Script BASH, tri par sélection dans tableau

Salut à vous,

@kholo, merci pour ce détail hyper pédagogique, j'ai compris la majorité des choses que tu as expliqué.
Bon, je ne vais pas te mentir, il va me falloir encore pas mal d'essais et de pratiques avant de maîtriser tout ça.

@watael et @pingouinux : je n'ai pas trop compris votre discussion. ^^
En gros cette ligne :

for element in $monTableau; do

Moi je l'interprète comme : pour chaque élement de tous les éléments de mon tableau.
Vu que j'ai créé la variable

monTableau=${tableaunote[*]}

qui contient toutes les valeurs.

Si c'est une erreur vous auriez mis quoi à la place de $monTableau ?
En tout cas j'ai fait plein d'essais et le script fonctionne correctement. smile

Hors ligne

#25 Le 25/03/2018, à 14:45

Watael

Re : Script BASH, tri par sélection dans tableau

tous les éléments du tableau, comme les arguments d'un script, sont rendus disponibles par @ => "${tableau[@]}"
avec des guillemets, il faut toujours mettre des guillemets !
$tableau est équivalent à ${tableau[0]}, càd le premier élément du tableau.

oui, c'est une erreur parce qu'un tableau peut contenir des éléments comportant des espaces :

monTableau=( 'un élément' "un autre élément" et\ un\ autre )

fait quelques essais avec/sans des guillemets, avec @ ou *, en passant par une variable "plate"...


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

Hors ligne