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 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 ;-)

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

redrum a écrit :

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

Alain.g a écrit :

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é hmm
En utilisant d'autres outils, oui bien sûr !


-- Lucid Lynx --

Hors ligne