#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.
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
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
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
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
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 ) :
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