#1 Le 03/09/2008, à 19:53
- anonyme1
[résolu] bash - chaîne de caractères awk bcle for
Bonjour,
Tout nouveau dans la programmation d'un script bash, je cherche à résoudre le petit élément de programme que voilà :
1- Hypothèse de base : Une liste Zenity contenant la liste à cocher suivante (checklist) :
Fruits_Pomme
Fruits_Poire
Fruits_Ananas
Fruits_Mangue
Fruits_Citron
Tous les composants de liste commenceront toujours pas "Fruits_"
2- Je peux choisir n'importe quel élément, un seul si je veux, tous si je veux. J'obtiens par exemple :
Fruits_Pomme|Fruits_Poire|Fruits_Ananas
3- Comme je ne peux jamais savoir à l'avance combien d'éléments l'utilisateur va sélectionner, je cherche à le calculer. Pas de problème avec la commande suivante :
nb_element_panier=`echo $liste | awk 'BEGIN{ FS="Fruits" }{ print NF-1 }'`
Pour ceux qui n'auraient pas déjà compris, ici nb_element_panier=3
4- Là où ça se gate, c'est que j'aimerais récupéré dans un vecteur chaque élément sélectionné et j'avoue sécher un peu (un comble pour un fruit!).
element_panier[1]=Fruits_Pomme
element_panier[2]=Fruits_Poire
element_panier[3]=Fruits_Ananas
J'ai pensé bêtement à la commande suivante qui est une hérésie informatique mais qui ressemble à la commande que j'aimerais utilisé :
if [ $nb_element_panier -eq 1 ]; then
element_panier[1]=$liste
else
for ((i=1 ; $nb_element_panier + 1 - $i ; i++))
do
element_panier[$i]="`echo $liste | awk -F'|' '{print $($i)}'`"
done
fi
Quelqu'un peut-il me débloquer ? Merci!
Dernière modification par redrum (Le 05/01/2009, à 17:53)
#2 Le 03/09/2008, à 20:47
- Totor
Re : [résolu] bash - chaîne de caractères awk bcle for
Salut,
Il est possible de créer et d'initialiser des tableaux en bash de la façon suivante :
nom_tableau=(ele1 ele2 ele3 ....)
Avec Fruits_Pomme|Fruits_Poire|Fruits_Ananas, tu as quasiment ce formalise.
Il faut simplement transformer les | en espace.
La transformation est facilement réalisable en bash en utilisant le principe de remplacement des paramètres avec la syntaxe ${paramètre//motif/chaîne} (cf. man bash).
admettons que la liste obtenue par zenity soit :
listeFruits="Fruits_Pomme|Fruits_Poire|Fruits_Ananas"
La transformation ce fait comme ceci :
listeFruits="Fruits_Pomme|Fruits_Poire|Fruits_Ananas"
liste=${listeFruits//|/ }
et voilà le tour est joué... tu as transformer ta chaine en ele1 ele2 ele3 ....
maitenant, construisons le tableau :
element_panier=(${liste})
Pour résumer, en supprimant l'affectation "liste" :
listeFruits="Fruits_Pomme|Fruits_Poire|Fruits_Ananas"
element_panier=(${listeFruits//|/ })
A noter que les indices du tableau commencent à 0.
Petite dernière chose :
Maintenant que tu as un tableau, il est très facile d'en connaitre le nombre d'éléments :
nb_element_panier=${#element_panier[@]}
Dernière modification par Totor (Le 03/09/2008, à 20:48)
-- Lucid Lynx --
Hors ligne
#3 Le 04/09/2008, à 20:16
- anonyme1
Re : [résolu] bash - chaîne de caractères awk bcle for
Merci pour l'astuce. Décidément, que ferais-je toi ?
Les pommes et les poires, c'était pour expliquer facilement.
En fait, je m'amuse à apprendre bash en créant un script pour me permettre d'automatiser le backup de mes DVD via un encodage en x264.
Le mkv permet d'encapusler plusieurs pistes de sous-titres et de son d'où le script suivant pour les sous-titres :
##!/bin/bash
function subtitle_ref {
## TO GIVE THE SUBTITLES TRACKS
DvdSlist=`mplayer -identify -vo null -ao null -frames 0 dvd://$title | grep "ID_SID"`
DvdSlistMatrix=(${DvdSlist})
DvdStrackNb=${#DvdSlistMatrix[@]}
for ((i=0 ; $DvdStrackNb - $i ; i++))
do
DvdStrack[$i]="FALSE `echo ${DvdSlistMatrix[$i]} | awk 'BEGIN{FS="_"} {print $3}'` `echo ${DvdSlistMatrix[$i]} | awk 'BEGIN{FS="="} {print $2}'`"
done
DivxSlist=$(zenity --title "DVD subtitle selection" --text "Select the subtitle track you wish to extract :" --list --checklist --column "" --column "sid" --column "slang" ${DvdStrack[@]})
echo $DivxSlist
SelectedSubtitleId=(${DivxSlist//|/ })
SelectedSubtitleNb=${#SelectedSubtitleId[@]}
echo -e $RED$"User has selected "$SelectedSubtitleNb$" subtitles tracks whose sid are : "${SelectedSubtitleId[@]}$WHITE
}
title=1
subtitle_ref
Avec ton aide, j'ai pu aboutir mais j'aimerais bien :
1- éviter systématique de créer une variable intermédiaire (ex. DvdSlist) avant de créer le tableau (ex. DvdSlistMatrix)
2- éviter la boucle for
Puis-je encore te demander tes lumières ?
Un grand merci en tout cas!
#4 Le 04/09/2008, à 20:39
- Totor
Re : [résolu] bash - chaîne de caractères awk bcle for
tu peux remplacer :
DvdSlist=`mplayer -identify -vo null -ao null -frames 0 dvd://$title | grep "ID_SID"`
DvdSlistMatrix=(${DvdSlist})
par :
DvdSlistMatrix=(`mplayer -identify -vo null -ao null -frames 0 dvd://$title | grep "ID_SID"`)
mais par contre, tu es obligé de passer par la variable DivxSlist pour construire SelectedSubtitleId
Tu confirmes Alain.g ?
Dernière modification par Totor (Le 04/09/2008, à 20:39)
-- Lucid Lynx --
Hors ligne
#5 Le 04/09/2008, à 22:13
- Alain.g
Re : [résolu] bash - chaîne de caractères awk bcle for
Bonsoir ;-)
mais par contre, tu es obligé de passer par la variable DivxSlist pour construire SelectedSubtitleId
Tu confirmes Alain.g ?
Non c'est tout a fait possible, on pourrait utiliser "| tr" ou "| sed" pour remplacer directement les "|" en espace, ou même changer provisoirement la valeur d'IFS, mais le plus simple est d'utiliser l'option --separator de zenity en choisissant l'espace.
SelectedSubtitleId=(`zenity --separator " " --list --checklist etc..etc... `)
on aurait pu choisir un autre espace blanc : --separator $'\t' (tabulation) ou --separator $'\n' (saut de ligne).
2- éviter la boucle for
le mieux serait d'oublier grep et de formater directement pour zenity grâce à sed ou awk
ça pourrait donner en tout (je te laisse le plaisir de trouver comment faire avec awk ou sed)
DvdStrack=$(mplayer -identify -vo null -ao null -frames 0 dvd://$title | awk -les_options_qui_vont_bien)
SelectedSubtitleId=(`zenity --separator " " --list --checklist --column "" --column "sid" --column "slang" $DvdStrack`)
$DvdStrack n'est pas un tableau dans mon exemple, mais on peut aussi en faire un tableau bien que je ne vois pas trop l'utilité dans ce cas
Si tu ne vois pas comment faire avec awk ou sed, n'hésite pas à demander ;-)
Dernière modification par Alain.g (Le 04/09/2008, à 22:33)
Xubuntu Karmic !
Hors ligne
#6 Le 05/09/2008, à 08:29
- Totor
Re : [résolu] bash - chaîne de caractères awk bcle for
Bonsoir ;-)
Totor a écrit :mais par contre, tu es obligé de passer par la variable DivxSlist pour construire SelectedSubtitleId
Tu confirmes Alain.g ?
Non c'est tout a fait possible, on pourrait utiliser "| tr" ou "| sed" pour remplacer directement les "|" en espace, ou même changer provisoirement la valeur d'IFS, mais le plus simple est d'utiliser l'option --separator de zenity en choisissant l'espace.
SelectedSubtitleId=(`zenity --separator " " --list --checklist etc..etc... `)
on aurait pu choisir un autre espace blanc : --separator $'\t' (tabulation) ou --separator $'\n' (saut de ligne).
Certe, mais ce que je voulais dire, c'est que ce n'est pas possible via le principe de remplacement des paramètres ? Je me suis mal exprimé
En utilisant d'autres outils, oui bien sûr !
-- Lucid Lynx --
Hors ligne