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 11/12/2012, à 15:16

Hizoka

multiselect, une version maison de la commande select

Bonjour smile

J'aime bien la commande select qui permet de créer une liste de choix, ex :

select valeur in "Chocolat" "Café" "Thé"
do
  echo "Vous préférez le ${valeur} ou le numero ${REPLY}"
  break
done

Mais que pourrait on donc amélioré dans cette commande ?
- La sélection multiple ?
- Une description pour chaque option ?
- Et pourquoi pas un peu de couleur ? smile

Ayant à la base surtout besoin du 1er point, je me suis donc penché sur la question pour créer une fonction bash me permettant de faire ce que je souhaite smile

Voici la fonction complète (Version du 15/12/12) :

function multiselect
{
# A multi select function created by Belleguic Terence [hizo@free.fr] with help of Watael, under licence by-nc-sa - Creative Commons

# valeur de retour numérique : ${multinum[@]}
# valeur de retour de texte : ${multitxt[@]}
# ${@} : les arguments servant de liste
# PS3 : message à afficher avant le listing
# @@ : élément séparateur, partie de gauche valeur texte et à gauche description ( valeur@@description )

# ATTENTION : La liste commence au chiffre 1 mais les tableaux retournés commencent, eux, à 0 (comme tout tableau)

# Valeurs pour la coloration => modification possible :)
FUSHIA="\033[1;35m"
RAZ="\033[1;0m"
BLEUFONCE="\033[1;34m"
VERT="\033[1;32m"
ROUGE="\033[1;31m"

# Message informatif apparaissant avant la liste
[[ ${PS3} ]] && echo -e "${FUSHIA}${PS3}${RAZ}\n" || echo ""

# Remise au propre des variables
unset multinum multitxt
local num x

# Affichage de la liste des choix ; for x = for x in "${@}"
for x
do
	# Incrémentation du numéro pour la prochaine ligne
	((num++))

	# recherche le signe servant de séparateur entre la valeur et la description
	if [[ "${x}" =~ "@@" ]]
	then
		# Si séparateur présent : affichage du numéro, de la valeur du texte et de la description
		echo -e "${FUSHIA}${num}${RAZ}) ${BLEUFONCE}${x%%@@*}${RAZ} : ${VERT}${x##*@@}${RAZ}"

	else
		# Si pas de séparateur : affichage du numéro et de la valeur du texte
		echo -e "${FUSHIA}${num}${RAZ}) ${BLEUFONCE}${x}${RAZ}"
	fi
done

# Envoie de la réponse dans un tableau
read -p $'\nSélection : ' -a multinum

# Création d'une liste contenant les valeurs textes choisies + Vérification des valeurs numériques
for x in "${multinum[@]}"
do
	# ${#} = ${#@} =
	if [[ ${x} -gt ${#} ]]
	then
		# Message d'erreur indiquant une réponse impossible
		echo -e "\n${ROUGE}Erreur dans la sélection, vous devez rentrez des chiffres inférieurs à la valeur maximale proposée.${RAZ}"

		# Destruction des variables
		unset multinum multitxt

		# Arrêt de la fonction en erreur (code 1)
		return 1

	else
		# Ajout de la valeur traitée dans le tableau
		multitxt+=("${!x%%@@*}")
	fi
done
}

Cette fonction permet donc de réaliser tout ce qui a été listé ci-dessus.

Et pour bien voir, rien ne vaut un bon exemple en couleur : http://ascii.io/a/1728

la commande utilisée dans l'exemple est celle-ci :

PS3="Liste des dépots installables"
multiselect "Back in time@@Depot Dev du logiciel de sauvegarde Back in time" \
"Clementine@@Depot Dev du logiciel de gestion musicale Clementine" \
"FFmpeg Dev@@Depot Dev du logiciel de lecture et encodage vidéo FFMpeg" \
"GCStar@@Depot Dev du logiciel de gestion de collection GCStar" \
"Gmediafinder@@Depot du logiciel de visionnage de video youtube GMediaFinder" \
"Gnome-Split@@Depot du logiciel de découpe/assemblage de fichier Gnome-Split" \
"Handbrake@@Depot du logiciel d'encodage vidéo Handbrake" \
"Kubuntu Backport" \
"Kubuntu Update"

avec pour commande retour :

for ((i=1; i<${#multitxt[@]}; i++))
do
 echo -e "J'ai choisi la valeur texte ${BLEUFONCE}${multitxt[${i}]}${NOIR} qui à pour valeur numerique ${FUSHIA}${multinum[${i}]}${NOIR}."
done

Ca vous tente ?
Alors voici les options :
- Les valeurs numérique de retour sont contenu dans la liste : ${multinum[@]}
- Les valeurs texte de retour sont contenu dans la liste : ${multitxt[@]}
- Pour afficher un Intituler à la liste, il faut utiliser la variable PS3 (comme select), si pas de valeur, alors il y a un saut de ligne
- Pour séparer la valeur texte et sa description, il faut utiliser @@ (valeur texte@@description de la valeur) (cette option n'est pas obligatoire)
- ATTENTION : les valeurs de la liste commencent à 1 mais comme pour tout tableaux, les valeurs de ${multinum[@]} et
${multitxt[@]} commencent à 0 (si mon choix est "Back in time"|1, les variables seront ${multinum[0]} et ${multitxt[0]} )

Voila, n’hésitez pas à me faire des retours pour améliorer, simplifier, développer le code smile (ou simplement critiquer tongue)

Dernière modification par Hizoka (Le 16/12/2012, à 12:36)


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

Hors ligne

#2 Le 11/12/2012, à 17:52

H4nnibal

Re : multiselect, une version maison de la commande select

Bonjour,

ton script a l'air bien sympathique, je le garde sous la main ça peut toujours servir smile


/* No comment*/

Hors ligne

#3 Le 12/12/2012, à 01:47

Watael

Re : multiselect, une version maison de la commande select

Salut,

c'est plutôt pas mal.

# Utilisation d'une liste afin de lister les arguments
valeurs=( "${@}" )

# Affichage de la liste des choix
for x in ${!valeurs[@]}

ceci n'est pas utile : $@ est déjà ± un tableau.
une forme elliptique de la boucle for

for var do :stuff with $var; done

liste les éléments de "$@"

$ maFonc(){ for var do echo "$var"; done;}
$ maFonc foo bar\ baz "foo bar"
foo
bar baz
foo bar

de plus, valeurs est un tableau indexé, donc ${!valeurs[@]} retourne les index, pour finalement n'utiliser l'index pour numéroter la liste qu'une seule fois. Autant incrémenter un compteur.

multinum ne me semble pas un tableau utile, vu que $REPLY est une liste de nombre.


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

Hors ligne

#4 Le 12/12/2012, à 04:17

Hizoka

Re : multiselect, une version maison de la commande select

salut smile

J'ai un peu de mal à suivre, voila ou j'en suis (la derniere ligne me pose soucis au final :

function multiselect
{
# Message explicatif
[[ ${PS3} ]] && echo -e "${FUSHIA}${PS3}${NOIR}\n" || echo ""

# Remise au propre des variables
unset multinum multitxt PS3 num valeur x

# Affichage de la liste des choix
# La boucle for utilise automatiquement les arguments donnés à la fonction
for valeur
do
	# recherche le signe servant de séparateur entre la valeur et la description
	if [[ "${valeur}" =~ "@@" ]]
	then
		# Si séparateur présent : affichage du numero, de la valeur du texte et de la description
		echo -e "${FUSHIA}${num:-0}${NOIR}) ${BLEUFONCE}${valeur%%@@*}${NOIR} : ${VERT}${valeur##*@@}${NOIR}"
	else
		# Si pas de séparateur : affichage du numero et de la valeur du texte
		echo -e "${FUSHIA}${num}${NOIR}) ${BLEUFONCE}${valeur}${NOIR}"
	fi

	# Incrementation du numero pour la prochaine ligne
	((num++))
done
echo ""

# Attente de la réponse
read -p "Selection : "

# Vérification des valeurs
for x in ${REPLY}; do [[ ${valeur} -gt "${#@}" ]] && { echo -e "\n${ROUGE}Erreur dans la sélection, vous devez rentrez des chiffres et inférieurs à la valeur maximale proposée.${NOIR}"; return; }; done

# Creation d'une liste contenant les valeurs numeriques choisies
multinum=(${REPLY})

# Creation d'une liste contenant les valeurs textes choisies
#### ====>>> La je vois pas comment faire si je n'ai plus de tableau valeurs
for x in ${multinum[@]}; do multitxt+=("${valeurs[${x}]%%@@*}"); done
}

De même, si multinum n'est pas un tableau, difficile de faire la correspondance entre la valeur numérique et la valeur texte non ?

par ex, pour connaitre la valeur numérique de ${multitxt[2]}, comment fais-tu ?
car via le tableau, je sais que c'est ${multinum[2]}.

Désolé si j'ai un peu de mal, merci de m'expliquer smile


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

Hors ligne

#5 Le 12/12/2012, à 04:55

Watael

Re : multiselect, une version maison de la commande select

tu dois maintenant te servir des paramètres positionnels que contient $@ ($1, $2...)
num doit donc être incrémenté avant l'affichage, qui se fera à partir de 1.


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

Hors ligne

#6 Le 12/12/2012, à 05:47

Hizoka

Re : multiselect, une version maison de la commande select

Bien vu, ca marche mais j'en reviens à :

De même, si multinum n'est pas un tableau, difficile de faire la correspondance entre la valeur numérique et la valeur texte non ?

par ex, pour connaitre la valeur numérique de ${multitxt[2]}, comment fais-tu ?
car via le tableau, je sais que c'est ${multinum[2]}.

Je parle bien évidemment pour l'utilisateur qui aurait besoin par ex de récupérer la 2eme valeur rentrée une fois la fonction exécutée.

function multiselect
{
# Message explicatif
[[ ${PS3} ]] && echo -e "${FUSHIA}${PS3}${NOIR}\n" || echo ""

# Remise au propre des variables
unset multinum multitxt PS3 num x

# Affichage de la liste des choix
# La boucle for utilise automatiquement les arguments donnés à la fonction
for x
do
	# Incrementation du numero pour la prochaine ligne
	((num++))

	# recherche le signe servant de séparateur entre la valeur et la description
	if [[ "${x}" =~ "@@" ]]
	then
		# Si séparateur présent : affichage du numero, de la valeur du texte et de la description
		echo -e "${FUSHIA}${num}${NOIR}) ${BLEUFONCE}${x%%@@*}${NOIR} : ${VERT}${x##*@@}${NOIR}"
	else
		# Si pas de séparateur : affichage du numero et de la valeur du texte
		echo -e "${FUSHIA}${num}${NOIR}) ${BLEUFONCE}${x}${NOIR}"
	fi

	done
echo ""

# Attente de la réponse
read -p "Selection : "

# Vérification des valeurs
for x in ${REPLY}; do [[ ${x} -gt "${#@}" ]] && { echo -e "\n${ROUGE}Erreur dans la sélection, vous devez rentrez des chiffres et inférieurs à la valeur maximale proposée.${NOIR}"; return; }; done

# Creation d'une liste contenant les valeurs textes choisies
for x in ${REPLY}; do multitxt+=("${!x%%@@*}"); done
}

Dernière modification par Hizoka (Le 12/12/2012, à 06:41)


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

Hors ligne

#7 Le 12/12/2012, à 14:21

Watael

Re : multiselect, une version maison de la commande select

Je parle bien évidemment pour l'utilisateur qui aurait besoin par ex de récupérer la 2eme valeur rentrée une fois la fonction exécutée.

Je ne comprends pas.
Il utilise le tableau multitxt.

Encore une petite chose: le test d'une regex peut être remplacé par un case

   case ${x} in
      # Si séparateur présent : affichage du numero, de la valeur du texte et de la description
      *@@*) echo "${num}) ${x%%@@*} : ${x##*@@}" ;;
      # Si pas de séparateur : affichage du numero et de la valeur du texte
      *) echo "${num}) ${x}"
   esac

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

Hors ligne

#8 Le 12/12/2012, à 19:34

Hizoka

Re : multiselect, une version maison de la commande select

Salut,

On peut eviter le test de reg avec case mais aussi avec if non ?

[[ $x == *@@* ]]

C'est aussi efficace dans les 2 cas ?

En admettant que le codeur utilise les valeurs numeriques et non les valeurs de texte

for x in $REPLY
do
  case x in
    1) ...
    2)...
  esac
done

comment peut il faire pour connaitre le 3e choix sur 5 par ex sans passer par un compteur ou quoi que ce soit ?

Car dans mon ex, le retour est le suivant :

for ((i=0; i<${#multitxt[@]}; i++))
do
 echo -e "J'ai choisi la valeur texte ${BLEUFONCE}${multitxt[${i}]}${NOIR} qui à pour valeur numerique ${FUSHIA}${multinum[${i}]}${NOIR}."
done

Comment fais tu pour indiquer le numero de chaque valeur texte ?

Je pense que nos niveau sont trop differents tongue
Tu ne dois pas forcement comprendre  ce que je dis car tu ne ferais pas comme ça ou n'en comprends pas l'utilité...

Une derniere chose, mon but etant que ce soit accessible aux débutants, penses tu que le fait que la liste debute a 1 mais que le tableaux debut lui debute à 0 puisse perturber ?

Merci pour le temps que tu me consacres smile


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

Hors ligne

#9 Le 12/12/2012, à 22:57

Watael

Re : multiselect, une version maison de la commande select

Comment fais tu pour indiquer le numero de chaque valeur texte ?

bah! ${!x} c'est le texte.
alors, $x est l'"index", le numéro de paramètre positionnel.

for x in ${REPLY}
do
   echo -e "J'ai choisi la valeur texte ${!x%%@@*} qui à pour valeur numérique $x."
   multitxt+=("${!x%%@@*}")
done

penses tu que le fait que la liste debute a 1 mais que le tableaux debut lui debute à 0 puisse perturber ?

oui, il faudrait peut-être le leur préciser en commentaire.


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

Hors ligne

#10 Le 13/12/2012, à 19:02

Hizoka

Re : multiselect, une version maison de la commande select

Hé hé on a du mal tongue

imagine, le mec exécute la fonction avec pour choix 1 3 5

plus tard, il a besoin de ces valeurs, pour les valeurs textes il peut les ressortir comme il veut via multitxt (tant que la fonction n'a pas été relancée) mais avec REPLY, 2 soucis :
- il ne peut pas sortir le 2e nombre par ex (de façon simple et rapide)
- la variable REPLY risque de s'être fait modifié par un autre read...
de ce fait, je pense qu'il faille laisser cette variable qui ne servira pas à tout le monde mais qui ne coûte pas grand chose smile


J'ajouterai un Warning pour la différence entre numérotation tableaux et liste.


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

Hors ligne

#11 Le 13/12/2012, à 20:08

Watael

Re : multiselect, une version maison de la commande select

REPLY n'est pas inéluctable: on peut choisir le nom de la variable où read stocke les données.
Tu t'en sers pour coller au plus près de ce dont se sert select, mais est-ce bien nécessaire ?

Si tu veux continuer de te servir du tableau multinum, au moins fait comme ça

read -p'Selection : ' -a multinum

s'il te plaît wink


Oui, nous avons un problème de communication.
En effet, nos points de vue sont sûrement différents.


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

Hors ligne

#12 Le 14/12/2012, à 08:55

Hizoka

Re : multiselect, une version maison de la commande select

read -p'Selection : ' -a multinum

Parfait ça smile

Oui, nous avons un problème de communication.
En effet, nos points de vue sont sûrement différents.

Au pire ça fait une variable en rab, rien de bien méchant smile
et il y aura toujours quelqu'un qui pourrait en avoir besoin tongue

Ca donne donc :

function multiselect
{
# A multi select function by Hizoka, under licence by-nc-sa - Creative Commons

# Message explicatif
[[ ${PS3} ]] && echo -e "${FUSHIA}${PS3}${NOIR}\n" || echo ""

# Remise au propre des variables
unset multinum multitxt num x

# Affichage de la liste des choix
# La boucle for utilise automatiquement les arguments donnés à la fonction
for x
do
	# Incrementation du numero pour la prochaine ligne
	((num++))

	# recherche le signe servant de séparateur entre la valeur et la description
	if [[ "${x}" =~ "@@" ]]
	then
		# Si séparateur présent : affichage du numero, de la valeur du texte et de la description
		echo -e "${FUSHIA}${num}${NOIR}) ${BLEUFONCE}${x%%@@*}${NOIR} : ${VERT}${x##*@@}${NOIR}"
	else
		# Si pas de séparateur : affichage du numero et de la valeur du texte
		echo -e "${FUSHIA}${num}${NOIR}) ${BLEUFONCE}${x}${NOIR}"
	fi

	done
echo ""

# Envoie de la réponse dans un tableau
read -p "Selection : "  -a multinum

# Création d'une liste contenant les valeurs textes choisies + Vérification des valeurs numeriques
for x in ${multinum[@]}
do
	if [[ ${x} -gt "${#@}" ]]
	then
		echo -e "\n${ROUGE}Erreur dans la sélection, vous devez rentrez des chiffres inférieurs à la valeur maximale proposée.${NOIR}"
		unset multinum multitxt
		return 1
	else
		multitxt+=("${!x%%@@*}")
	fi
done
}

Tu vois d'autres façons d’améliorer le truc ? (j'en ai profité pour regrouper les 2 boucles for de fin)

Merci à toi !!

Dernière modification par Hizoka (Le 14/12/2012, à 10:20)


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

Hors ligne

#13 Le 14/12/2012, à 11:51

Watael

Re : multiselect, une version maison de la commande select

le fond de mon terminal est noir, je ne vais donc pas être très content si tu changes la couleur de mon affichage.
plutôt que de remettre à noir, annule la mise en forme

rst="\e[m"

je préfère printf à echo -e, ça permet une meilleure distinction entre le format et les données.

$ rouge="\e[01;31m"
$ printf "$rouge%s$rst\n" "bla bla"

les tableaux doivent être mis entre guillemets, sinon la boucle for va prendre chaque mot distinctement, au lieu de boucler sur les éléments.
ici, ça ne porte pas à conséquence, puisqu'il n'y a que des nombres, mais pour donner l'exemple, il vaut mieux le faire systématiquement.

"${#@}" n'est pas utile (les guillemets non plus), simplement $# wink


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

Hors ligne

#14 Le 14/12/2012, à 22:28

Hizoka

Re : multiselect, une version maison de la commande select

le fond de mon terminal est noir, je ne vais donc pas être très content si tu changes la couleur de mon affichage.
plutôt que de remettre à noir, annule la mise en forme

OK, c'est en effet mieux.

je préfère printf à echo -e, ça permet une meilleure distinction entre le format et les données.

Pour le coup je préfère echo -e smile je trouve ca plus lisible (et surtout c'est une habitude tongue )

les tableaux doivent être mis entre guillemets, sinon la boucle for va prendre chaque mot distinctement, au lieu de boucler sur les éléments.

OK

"${#@}" n'est pas utile (les guillemets non plus), simplement $#

Je ne savais pas qu'on pouvait virer le @.
Pour les ", c'était une question de coloration de syntaxe sur mon éditeur tongue
Et je préfère toujours mettre les {} autour de variables afin de ne pas perdre mon habitude (bonne ?)
Du coup, je passe à ${#} (ça c'est du compromis smile )

echo ""

# Envoie de la réponse dans un tableau
read -p "Selection : "  -a multinum

est-il possible de faire un saut de ligne dans read via \n ?
car j'y arrive pas comme ca, uniquement avec :

read -p "
Selection : "  -a multinum
function multiselect
{
# A multi select function created by Belleguic Terence with help of Watael, under licence by-nc-sa - Creative Commons

# valeur de retour numérique : ${multinum[@]}
# valeur de retour de texte : ${multitxt[@]}
# ${@} : les arguments servant de liste
# PS3 : message à afficher avant le listing
# @@ : élément séparateur, partie de gauche valeur texte et à gauche description ( valeur@@description )

# ATTENTION : La liste commence au chiffre 1 mais les tableaux retournés commencent, eux, à 0 (comme tout tableau)

# Variables pour les couleurs
FUSHIA="\033[1;35m"
RAZ="\e[m"
BLEUFONCE="\033[1;34m"
VERT="\033[0;32m"
ROUGE="\033[1;31m"

# Message informatif apparaissant avant la liste
[[ ${PS3} ]] && echo -e "${FUSHIA}${PS3}${RAZ}\n" || echo ""

# Remise au propre des variables
unset multinum multitxt num x

# Affichage de la liste des choix ; for x = for x in "${@}"
for x
do
	# Incrémentation du numéro pour la prochaine ligne
	((num++))

	# recherche le signe servant de séparateur entre la valeur et la description
	if [[ "${x}" =~ "@@" ]]
	then
		# Si séparateur présent : affichage du numéro, de la valeur du texte et de la description
		echo -e "${FUSHIA}${num}${RAZ}) ${BLEUFONCE}${x%%@@*}${RAZ} : ${VERT}${x##*@@}${RAZ}"

	else
		# Si pas de séparateur : affichage du numéro et de la valeur du texte
		echo -e "${FUSHIA}${num}${RAZ}) ${BLEUFONCE}${x}${RAZ}"
	fi
done

# Saut de ligne esthétique
echo ""

# Envoie de la réponse dans un tableau
read -p "Sélection : "  -a multinum

# Création d'une liste contenant les valeurs textes choisies + Vérification des valeurs numériques
for x in "${multinum[@]}"
do
	# ${#} = ${#@} =
	if [[ ${x} -gt ${#} ]]
	then
		# Message d'erreur indiquant une réponse impossible
		echo -e "\n${ROUGE}Erreur dans la sélection, vous devez rentrez des chiffres inférieurs à la valeur maximale proposée.${RAZ}"

		# Destruction des variables
		unset multinum multitxt

		# Arrêt de la fonction en erreur (code 1)
		return 1

	else
		# Ajout de la valeur traitée dans le tableau
		multitxt+=("${!x%%@@*}")
	fi
done
}

Jai ajouté :
- Ton nom quand même après tout le temps passé à m'aider tongue
- Le message indiquant la différence de nombre entre la liste et le tableau
- Corrigé les fautes
- détaillé un peu plus la fonction

ça devient plutot pas mal tout ça smile

Encore merci, car tu améliores la fonction mais surtout tu m'apprends des choses pratiques !!


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

Hors ligne

#15 Le 14/12/2012, à 23:17

Watael

Re : multiselect, une version maison de la commande select

Du coup, je passe à ${#} (ça c'est du compromis smile )

lol

pour faire un alinea dans le texte du prompt de read, il y a plusieurs solutions
- comme tu fais.
- avec $' ' (voir les paragraphe sur les protections dans le man de bash) : read -p $'\nSelection : '
- avec un code d'échappement ANSI: read -p '^[ESelection : ', ou ^[ est 'Ctrl-V Ctrl-[', et [ est 'Alt Gr-('

plutôt que de faire un unset des variables utilisées dans la fonction, déclare-les en tant que locales, soit en les déclarant dans la fonction avec declare ou typeset (puisqu'une variable déclarée dans un fonction est par défaut locale), ou avec local (ceci a le mérite d'être clair).


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

Hors ligne

#16 Le 15/12/2012, à 03:52

Hizoka

Re : multiselect, une version maison de la commande select

- avec $' ' (voir les paragraphe sur les protections dans le man de bash) : read -p $'\nSelection : '

mince... je connaissais le truc en plus...

ok pour les locales, c'est vrai que je ne pense jamais a utiliser les var local...

ce qui donne donc :

function multiselect
{
# valeur de retour numérique : ${multinum[@]}
# valeur de retour de texte : ${multitxt[@]}
# ${@} : les arguments servant de liste
# PS3 : message à afficher avant le listing
# @@ : élément séparateur, partie de gauche valeur texte et à gauche description ( valeur@@description )

# ATTENTION : La liste commence au chiffre 1 mais les tableaux retournés commencent, eux, à 0 (comme tout tableau)

# Message informatif apparaissant avant la liste
[[ ${PS3} ]] && echo -e "${FUSHIA}${PS3}${RAZ}\n" || echo ""

# Remise au propre des variables
unset multinum multitxt
local num x

# Affichage de la liste des choix ; for x = for x in "${@}"
for x
do
	# Incrémentation du numéro pour la prochaine ligne
	((num++))

	# recherche le signe servant de séparateur entre la valeur et la description
	if [[ "${x}" =~ "@@" ]]
	then
		# Si séparateur présent : affichage du numéro, de la valeur du texte et de la description
		echo -e "${FUSHIA}${num}${RAZ}) ${BLEUFONCE}${x%%@@*}${RAZ} : ${VERT}${x##*@@}${RAZ}"

	else
		# Si pas de séparateur : affichage du numéro et de la valeur du texte
		echo -e "${FUSHIA}${num}${RAZ}) ${BLEUFONCE}${x}${RAZ}"
	fi
done

# Envoie de la réponse dans un tableau
read -p $'\nSélection : ' -a multinum

# Création d'une liste contenant les valeurs textes choisies + Vérification des valeurs numériques
for x in "${multinum[@]}"
do
	# ${#} = ${#@} =
	if [[ ${x} -gt ${#} ]]
	then
		# Message d'erreur indiquant une réponse impossible
		echo -e "\n${ROUGE}Erreur dans la sélection, vous devez rentrez des chiffres inférieurs à la valeur maximale proposée.${RAZ}"

		# Destruction des variables
		unset multinum multitxt

		# Arrêt de la fonction en erreur (code 1)
		return 1

	else
		# Ajout de la valeur traitée dans le tableau
		multitxt+=("${!x%%@@*}")
	fi
done
}

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

Hors ligne