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 20/09/2011, à 10:26

bikarfioul

Select CASE avec un nombre de réponse possible indéfini

Salut,

J'ai trouvé ce bout de code sur la toile mais je trouve la façon de gérer la réponse ("${list[$REPLY-1]}") un peu hasardeuse
Auriez-vous une autre idée sur la façon de s'y prendre ?

PS3="Quel site souhaitez-vous activer ? : >" 
  listoff=(`ls /etc/apache2/sites-available/`)
  liston=(`ls /etc/apache2/sites-enabled/`)
  list=()
  for i in "${listoff[@]}"; do
  skip=
  for j in "${liston[@]}"; do
  [[ $i == $j ]] && { skip=1; break; }
  done
  [[ -n $skip ]] || list+=("$i")
  done
  declare -p list
   
  select CHOIX3 in "${list[@]}" "quitter (q|Q)" ; do
    case $REPLY in
        Q*|q*) echo "Au revoir"
        break;;
        *) a2ensite "${list[$REPLY-1]}"
        break
        ;;
    esac
done

Hors ligne

#2 Le 17/08/2012, à 13:37

Hizoka

Re : Select CASE avec un nombre de réponse possible indéfini

je déterre ce sujet, car j'ai un cas un peu similaire...


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

Hors ligne

#3 Le 18/08/2012, à 08:49

Watael

Re : Select CASE avec un nombre de réponse possible indéfini

salut,

pour moi c'est plutôt les boucles imbriquées qui me gênent.
je préfère l'approche à base de tableau associatif

$ arr1=( foo bar baz )
$ arr2=( foobar foo barbaz bar barfoo baz )
$ declare -A list; for i in "${arr1[@]}" "${arr2[@]}"; do pre[$i]+=1; done
$ sort <(printf '%s\n' "${!pre[@]}")
bar
barbaz
barfoo
baz
foo
foobar

et on met la sortie triée dans (encore) un autre tableau.
les deux premiers tableaux, s'il s'agit de listes de fichiers, ne sont pas forcément utiles.

Hizoka a écrit :

j'ai un cas un peu similaire...

on peut avoir des détails ?

Dernière modification par Watael (Le 18/08/2012, à 08:54)


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

Hors ligne

#4 Le 18/08/2012, à 10:55

Hizoka

Re : Select CASE avec un nombre de réponse possible indéfini

Perso j'ai un select + case.

J'ajoute regulierement des valeurs dans le select (que je classe dans l'ordre alphabetique), de ce fait mon case se decale et je dois remettre à jour toutes les valeurs...

J'aurais aimé qu'on puisse faire :

x=0
case $val in
 ((x+1)) )
 ((x+1)) )
....

ainsi plus besoin de modifier toutes les valeurs, il l'aurait fait lui meme.
Mais cela n'incremente pas la valeur x à chaque fois.

voila mon cas concret, mais je pense que j'ai fait compliqué... je voulais un select à valeur multiple, donc il faut passer par la valeur $REPLY, et case ne prenant pas une liste de valeur mais une seule, je dois le foutre dans une boucle for (sinon je peux remplacer le case par un if interminable...) :

select choix in "Back in time Dev" "Backport de KDE" "Clementine Dev" "FFmpeg Dev" "Foxit Reader" "Gmediafinder" "Gnome-Split" "Handbrake" "Mes ppa" "MKClean" "MKVToolNix" "Jdownloader" "Play On Linux" "Smplayer Dev" "Skrooge Dev" "The Gimp Dev" "Virtualbox Dev" "vlc Stable" "vlc Dev" "YAD - yet another dialog" "Exit"
do
	for caca in ${REPLY}
	do
		case ${caca} in
			1) # Back in time Dev
				log+="backintime-kde "
				sudo add-apt-repository -y ppa:bit-team/stable

				# si cron ne contient pas deja la commande, on l'ajoute
				[[ -z $(crontab -l | grep "/usr/bin/backintime") ]] && { crontab -l; echo "@reboot nice -n 19 ionice -c2 -n7 /usr/bin/backintime --backup-job >/dev/null 2>&1"; } | crontab - ;;

			2) # Backport de KDE
				sudo add-apt-repository -y ppa:kubuntu-ppa/backports ;;

			3) # Clementine Dev
				log+="clementine "
				sudo add-apt-repository -y ppa:me-davidsansome/clementine ;;

			4) # FFmpeg Dev
				log+="ffmpeg "
				sudo add-apt-repository -y ppa:jon-severinsson/ffmpeg ;;

			5) # Foxit Reader
				log+="foxit-installer "
				sudo add-apt-repository -y ppa:ed10vi86/ppa ;;

			6) # Gmediafinder
				log+="gmediafinder "
				sudo add-apt-repository -y ppa:s-lagui/ppa ;;

			7) # Gnome-Split
				log+="gnome-split "
				sudo add-apt-repository -y ppa:gnome-split-team/ppa ;;

			8) # Handbrake
				log+="handbrake-gtk "
				sudo add-apt-repository -y ppa:stebbins/handbrake-snapshots ;;

			9) # Mes ppa
				log+="screencastor zenitor mkv-extractor-gui "
				sudo add-apt-repository -y ppa:hizo/screencastor
				sudo add-apt-repository -y ppa:hizo/mkv-extractor-gui
				sudo add-apt-repository -y ppa:hizo/zenitor ;;

			10) # MKClean
				log+="mkclean "
				sudo add-apt-repository -y ppa:kampka/multimedia ;;

			11) # MKVToolNix
				log+="mkvtoolnix "
				echo "deb http://www.bunkus.org/ubuntu/oneiric/ ./" | sudo tee -a /etc/apt/sources.list
				wget -q https://www.bunkus.org/gpg-pub-moritzbunkus.txt -O- | sudo apt-key add - ;;

			12) # Jdownloader
				log+="jdownloader "
				sudo add-apt-repository -y ppa:jd-team/jdownloader ;;

			13) # Play On Linux
				log+="playonlinux "
				wget -q "http://deb.playonlinux.com/public.gpg" -O- | sudo apt-key add -
				sudo wget http://deb.playonlinux.com/playonlinux_precise.list -O /etc/apt/sources.list.d/playonlinux.list ;;

			14) # Smplayer Dev
				log+="smplayer "
				sudo add-apt-repository -y ppa:rvm/smplayer ;;

			15) # Skrooge Dev
				log+="skrooge "
				sudo add-apt-repository -y ppa:s-mankowski/beta ;;

			16) # The Gimp Dev
				log+="gimp "
				sudo add-apt-repository -y ppa:matthaeus123/mrw-gimp-svn ;;

			17) # Virtualbox Dev
				log+="virtualbox "
				echo "deb http://download.virtualbox.org/virtualbox/debian oneiric contrib" | sudo tee -a /etc/apt/sources.list
				wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add - ;;

			18) # vlc Stable
				log+="vlc "
				sudo add-apt-repository -y ppa:videolan/stable-daily ;;

			19) # vlc Dev
				log+="vlc "
				sudo add-apt-repository -y ppa:videolan/master-daily ;;

			20) # YAD - yet another dialog
				log+="yad "
				sudo add-apt-repository -y ppa:webupd8team/y-ppa-manager ;;
		esac
	done

	# Mise à jour
	UPDATE

	[[ ${log} ]] && sudo apt-get install -y ${log}

	break
done

mon code précédant était plus simple mais je ne voulais plus passer par dialog

Donc si tu as des idées d'amelioration smile

Dernière modification par Hizoka (Le 18/08/2012, à 10:57)


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

Hors ligne

#5 Le 18/08/2012, à 12:10

pingouinux

Re : Select CASE avec un nombre de réponse possible indéfini

Bonjour Hizoka,
Dans la boucle for, tu pourrais tester sur la variable choix au lieu de REPLY :

select choix in "Back in time Dev" "Backport de KDE"… "Exit"
do
	for caca in ${choix}
	do
		case ${caca} in
			"Back in time Dev" )
				log+="backintime-kde "
				sudo add-apt-repository -y ppa:bit-team/stable

				# si cron ne contient pas deja la commande, on l'ajoute
				[[ -z $(crontab -l | grep "/usr/bin/backintime") ]] && { crontab -l; echo "@reboot nice -n 19 ionice -c2 -n7 /usr/bin/backintime --backup-job >/dev/null 2>&1"; } | crontab - ;;

			"Backport de KDE" )
				sudo add-apt-repository -y ppa:kubuntu-ppa/backports ;;
..............................................................................................................

Hors ligne

#6 Le 18/08/2012, à 13:00

Watael

Re : Select CASE avec un nombre de réponse possible indéfini

toujours à base de tableaux associatifs

$ maFunc_1() { echo "nom de la fonction 1 : $FUNCNAME";}
$ maFunc_2() { echo "nom de la fonction 2 : $FUNCNAME";}
$ arr1[echo FUNCNAME 1]=maFunc_1
$ arr1[echo FUNCNAME 2]=maFunc_2
$ select fonct in "${!arr1[@]}"; do ${arr1[$fonct]}; break; done
1) echo FUNCNAME 2
2) echo FUNCNAME 1
#? 2
nom de la fonction 1 : maFunc_1

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

Hors ligne

#7 Le 18/08/2012, à 13:16

Hizoka

Re : Select CASE avec un nombre de réponse possible indéfini

pingouinux => impossible smile

select choix in "Back in time Dev" "Backport de KDE" "Clementine Dev" "FFmpeg Dev" "Foxit Reader" "Gmediafinder" "Gnome-Split" "Handbrake" "Mes ppa" "MKClean" "MKVToolNix" "Jdownloader" "Play On Linux" "Smplayer Dev" "Skrooge Dev" "The Gimp Dev" "Virtualbox Dev" "vlc Stable" "vlc Dev" "YAD - yet another dialog" "Exit"
do
 echo "reply : $REPLY
 choix : $choix"
 break
done
#? 5 15 20
reply : 5 15 20
choix :

deja testé et ca ne passe pas dans le cas de choix multiple.

Watael => je pige pas ca :

$ arr1[echo FUNCNAME 1]=maFunc_1
$ arr1[echo FUNCNAME 2]=maFunc_2

j'ai un peu de mal à piger le tout...
tu peux me refaire un exemple avec des explications et en utilisant quelques valeurs de mon cas stp ?


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

Hors ligne

#8 Le 18/08/2012, à 13:34

Watael

Re : Select CASE avec un nombre de réponse possible indéfini

$ unset arr1
$ BackInTimeDev() { log+="backintime-kde "; sudo add-apt-repository -y ppa:bit-team/stable;}
$ BackportKDE() { sudo add-apt-repository -y ppa:kubuntu-ppa/backports;}
$ declare -A arr1
$ arr1[Back in time Dev]=BackInTimeDev
$ arr1[Backport de KDE]=BackportKDE
$ select fonct in "${!arr1[@]}"; do ${arr1[$fonct]}; break; done
1) Backport de KDE
2) Back in time Dev
#?

c'est plus clair?


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

Hors ligne

#9 Le 18/08/2012, à 14:17

Hizoka

Re : Select CASE avec un nombre de réponse possible indéfini

en effet c'est sympa, je ne connaissais pas l'utilisation de ces tableaux (je ne connaissais que les version avec des numeros, pas avec du texte...)

Pratique mais dans mon cas necessite la creation de pas mal de fonctions et surtout ne permet pas la selection multiple :

#? 1 2
bash: arr1: mauvais indice de tableau

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

Hors ligne

#10 Le 18/08/2012, à 18:41

pingouinux

Re : Select CASE avec un nombre de réponse possible indéfini

@ Hizoka :
J'ai quelque chose à proposer, mais il y a peut-être plus simple. Il s'agit de générer ton script à partir d'un fichier de données.
Voici un exemple avec 3 rubriques.

Le fichier de données :

$ cat data
##### Gmediafinder
				log+="gmediafinder "
				sudo add-apt-repository -y ppa:s-lagui/ppa ;;
##### Foxit Reader
				log+="foxit-installer "
				sudo add-apt-repository -y ppa:ed10vi86/ppa ;;
##### Clementine Dev
				log+="clementine "
				sudo add-apt-repository -y ppa:me-davidsansome/clementine ;;

La rubrique doit être sur une ligne commençant par 4 # et un espace, suivie des commandes associées. L'ordre des rubriques est sans importance.

Le script qui va générer le tien :

$ cat gener_hizo.sh
debut_boucle=$(cat - <<"EOF"
do
	for caca in ${REPLY}
	do
		case ${caca} in
EOF
)

fin_boucle=$(cat - <<"EOF"
		esac
	done

	# Mise à jour
	UPDATE

	[[ ${log} ]] && sudo apt-get install -y ${log}

	break
done
EOF
)

declare -A commande
while read lig; do
   rubrik=$(sed -nr 's/^##### (.*)$/\1/p' <<<"$lig")
   [[ $rubrik ]] && rubrik_en_cours="$rubrik" || \
      commande["$rubrik_en_cours"]=${commande["$rubrik_en_cours"]}"$lig
"
done <data

alphabetik=$( for rubrik in "${!commande[@]}"; do echo "$rubrik"; done  | sort )

printf "%s " "select choix in"
while read rubrik; do
printf "\"%s\" " "$rubrik"
done <<<"$alphabetik"
printf "\n"

echo "$debut_boucle"

n=0;while read rubrik
do
   printf "\t\t\t%d) # %s\n" $((++n)) "$rubrik";
   while read lig; do printf "\t\t\t\t%s\n" "$lig"; done <<<"${commande["$rubrik"]}";
done <<<"$alphabetik"

echo "$fin_boucle"

Le résultat sort sur stdout, à rediriger.

$ ./gener_hizo.sh
select choix in "Clementine Dev" "Foxit Reader" "Gmediafinder" 
do
	for caca in ${REPLY}
	do
		case ${caca} in
			1) # Clementine Dev
				log+="clementine "
				sudo add-apt-repository -y ppa:me-davidsansome/clementine ;;
				
			2) # Foxit Reader
				log+="foxit-installer "
				sudo add-apt-repository -y ppa:ed10vi86/ppa ;;
				
			3) # Gmediafinder
				log+="gmediafinder "
				sudo add-apt-repository -y ppa:s-lagui/ppa ;;
				
		esac
	done

	# Mise à jour
	UPDATE

	[[ ${log} ]] && sudo apt-get install -y ${log}

	break
done

Hors ligne

#11 Le 18/08/2012, à 18:48

Hizoka

Re : Select CASE avec un nombre de réponse possible indéfini

ouais, c'est un chouille compliquer tongue
passer par plusieurs fichiers...

C'est un script qui contient de nombreuses fonctions, il me regroupe tout ce que j'utilise regulierement.

merci d'avoir reflechi comme ça smile


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

Hors ligne

#12 Le 19/08/2012, à 00:18

Hizoka

Re : Select CASE avec un nombre de réponse possible indéfini

Bon je viens de me faire un fork maison de select (avec un peu de couleur tongue) :

function multiselect
{
# valeur de retour : ${multinum[@]}
# valeur de retour : ${multitxt[@]}
# texte d'explication : ${PS3}
# $@ : les arguments

NOIR="\033[1;0m"
BLEUFONCE="\033[1;34m"
FUSHIA="\033[1;35m"

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

# Remise au propre des variables
unset x valeurs multinum multitxt

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

# Affichage de la liste des choix
for x in ${!valeurs[@]}; do echo -e "${FUSHIA}${x}${NOIR}) ${BLEUFONCE}${valeurs[${x}]}${NOIR}"; done

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

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

# Creation d'une liste contenant les valeurs textes choisies
for x in ${multinum[@]}; do multitxt+=("${valeurs[${x}]}"); done
}


multiselect "Back in time Dev" "Backport de KDE" "Clementine Dev" "Exit"

Veuillez choisir la ou les valeurs choisies parmis cette liste :

0) Back in time Dev
1) Backport de KDE
2) Clementine Dev
3) Exit

ca permet donc d'avoir 2 listes :
${multinum[@]} : qui contient les valeurs numériques
${multitxt[@]} : qui contient les valeurs textes

Bon ca change pas qu'il faut une boucle for pour le case ou des if...

Mais du coup ca me permet de ne plus passer par les valeurs numeriques mais leur texte, ainsi plus de soucis pour mettre à jour mon case.

mais ca ne resoud pas le probleme de base qu'a posé bikarfioul.

Franchement dommage que case et select n'autorise pas plusieurs infos...

Pour ceux que ça pourrait interresser :
Pour utiliser la liste des choix avec case avec seulement le 1er argument :

case "${multitxt[0]}" in
	"Back in time Dev") echo "Back in time Dev";;
	"Backport de KDE") echo "Backport de KDE" ;;
	"Clementine Dev") echo "Clementine Dev" ;;
	Exit)  return ;;
esac

Pour utiliser la liste des choix avec case avec tous les arguments :

for valeur in "${multitxt[@]}"
do
	case ${valeur} in
		"Back in time Dev") echo "Back in time Dev";;
		"Backport de KDE") echo "Backport de KDE" ;;
		"Clementine Dev") echo "Clementine Dev" ;;
		Exit)  return ;;
	esac
done

ou en utilisant les valeurs numeriques :

case "${multinum[0]}" in
	0) echo "Back in time Dev";;
	1) echo "Backport de KDE" ;;
	2) echo "Clementine Dev" ;;
	3)  return ;;
esac

et

for valeur in "${multinum[@]}"
do
	case ${valeur} in
		0) echo "Back in time Dev";;
		1) echo "Backport de KDE" ;;
		2) echo "Clementine Dev" ;;
		3)  return ;;
	esac
done

Une petite video avec les ex ci dessus : http://ascii.io/a/1014

Dernière modification par Hizoka (Le 19/08/2012, à 01:21)


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

Hors ligne