logo Debian Debian Debian-France Debian-Facile Debian-fr.org Forum-Debian.fr Debian ? Communautés logo inclusivité

Debian-facile

Bienvenue sur Debian-Facile, site d'aide pour les nouveaux utilisateurs de Debian.

Vous n'êtes pas identifié(e).

#1 23-10-2012 14:49:25

Franz
Membre
Distrib. : Squeeze
Noyau : 2.6.32-5-686
(G)UI : Gnome 2.30.2
Inscription : 08-05-2012

Comment faire un algorithme de bouclage sur des répertoires

J'espère ne pas être trop confus neutral


Suite à mon sujet sur l'encodage avec lame j'ai essayer de faire des boucles concernant les répertoires contenant mes fichiers wav.
Après  multiples tatonnements et en m'aidant de scripts d'exemples trouvés sur le net j'ai tout de même réussi à encoder une série de fichiers wav en mp3 dans un même répertoire en y positionnant le terminal et en lançant la ligne suivante:


for f in *.wav; do lame "$f" "${f%.wav}.mp3"; done



... ce qui crée le fichier en le renommant avec l'extention "mp3"


D'autre part j'ai fait aussi une commande pour créer des répertoires vides correspondants à toute la série  contenant les fichiers wav à encoder.
Les répertoires vides correspondants ainsi créés prennent le même nom que ceux d'origine avec un rajout de "-mp3" à la fin.

Voici la commande:

for i in * ;  do mkdir ${i}-mp3  ;  done



Jusque là ces deux commandes fonctionnent bien individuellement. Script-newbie est très fier lol

J'ai environ 70 répertoires contenant les wav
Mon problème concerne des boucles imbriquées qui permettraient de:


1. prendre le répertoire A (wav)
2. créer son compagnon (mp3) correspondant   (commande citée plus haut)
2. se placer dans le répertoire A (wav)
3. encoder les wav en mp3 dans A en les renommant   (commande citée plus haut)
4. les déplacer (fichiers générés mp3) dans le répertoire compagnon
5. prendre suivant (repertoire wav B) et refaire cet algorithme  ...etc...


J'avais fait aussi deux fonctions avec une boucle while et des for et j'ai trouvé le moyen de dupliquer et renommer des centaines de répertoires dans mon home. Heureusement j'ai pu effacer les dégats grâce à l'affichage par date mad


Les fonctions sont:

creer_rep ()
{
for i in *; do mkdir ${i}-mp3; done
}

encoder ()
{
for f in *.wav; do lame "$f" "${f%.wav}.mp3"; done
}



Si vous avez lu jusque là, vous avez deviné que je suis au bout de mes compétences et que mon obstination à faire ces fameuses  boucles a atteint ses limites. Sans solution je referai ce que j'ai déjà fait avec twolame à la main, répertoire après répertoire, mais dont le format n'est pas compatible avec mes lecteurs externes (tout est à recommencer).

Une meilleure idée est aussi la bienvenue  roll

Dernière modification par Franz (23-10-2012 14:58:37)


Vieux processeur amd sempron 3000+ cadencé à 2 Gz

Hors ligne

#2 23-10-2012 15:27:29

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : Comment faire un algorithme de bouclage sur des répertoires

Plutôt que de créer les répertoires pour tes mp3 d'un seul coup je ferai cela au coup par coup. Disons que ton programme devrait faire :
1) cd dans un répertoire de wav
2) tu convertis les wav en mp3
3) tu crées le nouveau répertoire pour les mp3
4) tu déplaces les mp3 vers le répertoire précédemment créé.

Je pense que cela devrait être piloté par une fonction que tu exécute pour chaque répertoire qui contient les wav

Tu peux donc garder ta fonction encoder. Mais la fonction creer_rep est inutile.

Disons que je verrais bien les choses de la façon suivante :


faire_le_boulot () {
   encoder
   dest="$(pwd)-mp3"
   mkdir "$dest"
   mv *.mp3 "$dest"
}
 



il faudra donc insérer cette fonction dans une boucle :


for d in <liste_de_répertoires>; do
  cd "$d"
  faire_le_boulot
  cd -
done
 


Il te reste à savoir comment faire pour avoir la <liste_de_répertoires>…

Hors ligne

#3 23-10-2012 16:57:54

Franz
Membre
Distrib. : Squeeze
Noyau : 2.6.32-5-686
(G)UI : Gnome 2.30.2
Inscription : 08-05-2012

Re : Comment faire un algorithme de bouclage sur des répertoires

Salut smile

Je suis en train d'essayer de comprendre tes routines car la manière dont tu vois les choses me paraît très bien. Je poserai les questions qui me seront nécessaires.


En attendant concernant la liste des répertoires dont le contenu est à encoder, j'avais trouvé une ligne de commande qui pourrait peut-être faire l'affaire sans liste et qui à priori lit les noms au fûr et à mesure (qui pourrait être intégrée dans le système de boucles ??)


De mémoire ça ressemblait à    peu près à ça:

find chemin-de-répertoires -type d | while read $ligne
do
bla bla   un  "$ligne"  quelque-part  bla bla
done



Est-ce que tu connais ce genre de truc ? Excuse-moi pour les bla bla yikes

J'ai trouvé ça aussi

LIGNES=$(find ./ -type d)
for LIGNE in $LIGNES
do
etc .........



Ce genre de code peut-il se substituer (ou se rajouter) à la boucle for que tu proposes sans avoir besoin de vraie liste ?

Dernière modification par Franz (23-10-2012 17:33:29)


Vieux processeur amd sempron 3000+ cadencé à 2 Gz

Hors ligne

#4 23-10-2012 17:30:03

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : Comment faire un algorithme de bouclage sur des répertoires

oui je connais très bien cette façon de faire. Tu pourrais faire comme cela :


find chemin-de-répertoires -type d | while read $ligne
do
  cd "$ligne"
  faire_le_boulot
  cd -
done
 



Avec cette manière de faire on peut modifier la façon de créer le répertoires des mp3  en donnant le nom du répertoire à faire_le_boulot. Cependant ça implique que chemin-de-répertoires soit donné en absolu à find… je te laisse imaginer comment faire les modifications nécessaires.
Sinon, cette façon de faire est parfaite.

Il y a une autre façon, qui est moins bien dans le cas où il y a beaucoup de répertoire mais qui présente d'autres avantages. La voici :


for d in $(find chemin-de-répertoires -type d); do  
  cd "$d"
  faire_le_boulot
  cd -
done
 


Voilà, je pense que ton problème est résolu.
Aussi, tu ferais bien d'ajouter les lignes qui sont valables pour bash mais pas pour dash :


#! /bin/bash
set -u
set -e
 



Le set -u permet de traiter comme une erreur les variables qui sont utilisées sans avoir été définies. Le set -e permet d'arrêter le script dès qu'un programme à un code de retour non nul. C'est une sécurité quand on teste.

Hors ligne

#5 23-10-2012 17:38:27

Franz
Membre
Distrib. : Squeeze
Noyau : 2.6.32-5-686
(G)UI : Gnome 2.30.2
Inscription : 08-05-2012

Re : Comment faire un algorithme de bouclage sur des répertoires

Tu es rapide comme l'éclair ! mon rajout est passée au travers big_smile


Je planche sur tout ça ! c'est bien la première fois que je dois faire bouillir autant mes neurones. En tout cas c'est très intéressant de découvrir ce système de script bash.

Merci en attendant mes questions si tu permets, mais ce sera demain smile

Dernière modification par Franz (23-10-2012 17:40:14)


Vieux processeur amd sempron 3000+ cadencé à 2 Gz

Hors ligne

#6 24-10-2012 10:42:30

Franz
Membre
Distrib. : Squeeze
Noyau : 2.6.32-5-686
(G)UI : Gnome 2.30.2
Inscription : 08-05-2012

Re : Comment faire un algorithme de bouclage sur des répertoires

Je viens d'être confronté à un problème de terminal dû à une erreur de syntaxe (des accolades vides à l'appel d'une fonction) ... 3 heures pour trouver.

Pour suivre le déroulement du script et comme je suis débutant, j'utilise echo et read et ça va bien pour expérimenter dans le script et pour essayer de comprendre ce que font les variables et leurs modifications.


Il y a des situations ça ne fonctionne plus, l'attente d'une entrée clavier ne se fait plus et le terminal se ferme.
et je ne peux plus faire des essais.


Comment savoir si c'est dû à une erreur de syntaxe ?
Comment forcer le terminal à rester ouvert quoi qu'il arrive ?
Comment vider toutes les variables avant de lancer le script ?
Est-ce qu'elles restent dans la mémoire entre chaque modification du script ?

Dernière modification par Franz (24-10-2012 12:02:10)


Vieux processeur amd sempron 3000+ cadencé à 2 Gz

Hors ligne

#7 24-10-2012 17:14:58

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : Comment faire un algorithme de bouclage sur des répertoires

Il faudrait voir le script complet.
Et aussi comment fais-tu pour le lancer ? Normalement il faut tout écrire dans un fichier et le rendre exécutable.


  $ chmod u+x mon-script.sh
 


en supposant que ton script s'appelle mon-script.sh
Ensuite pour l'exécuter :


  $ ./mon-script.sh
 


En attendant de voir ton script, je ne peux pas mieux te proposer.

Hors ligne

#8 24-10-2012 17:40:22

Franz
Membre
Distrib. : Squeeze
Noyau : 2.6.32-5-686
(G)UI : Gnome 2.30.2
Inscription : 08-05-2012

Re : Comment faire un algorithme de bouclage sur des répertoires

smile

Je lance le script dans le répertoire oû se trouvent les répertoires wav à encoder et ça marche bien pour mettre au point le script.
Je l'édite dans gedit qui a les couleurs automatiques. Un éditeur qui retourne les erreurs serait l'idéal pour moi qui découvre ce langage.


Quand tout fonctionnera je posterai le code. En tout cas j'y ai passé la journée et je n'ai pas réussi complétement. J'ai lancé le script des dizaines de fois lol

Vieux processeur amd sempron 3000+ cadencé à 2 Gz

Hors ligne

#9 24-10-2012 17:51:01

smolski
quasi...modo
Lieu : AIN
Distrib. : backports (buster) 10
Noyau : Linux 4.19.0-8-amd64
(G)UI : gnome
Inscription : 21-10-2008

Re : Comment faire un algorithme de bouclage sur des répertoires

Un éditeur qui retourne les erreurs serait l'idéal


Pour cela, j'utilise vim-nox.
voir le tuto :
vim-nox


saque eud dun (patois chtimi : fonce dedans)

Hors ligne

#10 24-10-2012 18:08:45

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : Comment faire un algorithme de bouclage sur des répertoires

Si tu me (nous) montrai le script, je (nous) pourrai (pourrions) expliquer les erreurs.
Au fait, si tu veux une explication sur une syntaxe particulière dans le code que je t'ai proposé, demande la, n'hésites surtout pas.

Si tu as peur de montrer tes erreurs, je comprend. Mais bon on en est tous passé par là smile

Hors ligne

#11 24-10-2012 19:14:40

Franz
Membre
Distrib. : Squeeze
Noyau : 2.6.32-5-686
(G)UI : Gnome 2.30.2
Inscription : 08-05-2012

Re : Comment faire un algorithme de bouclage sur des répertoires

Voici le script après modifications diverses pour un bon fonctionnement.
Je donnerai des commentaires plus tard et il faut mettre un fichier wav dans le répertoire principal pour que ça fonctionne sinon fermeture du terminal au début.
En effet je ne sais pas faire un test exist avec une extention de fichier.


On m'appelle à la soupe  big_smile
Merci à vous


#! /bin/bash

# version 4 - Bon pour chercher et afficher le chemin des répertoires wav et ceux des mp3 encodés (nom + mp3)
#  version 5 - Bon pour créer les répertoires mp3
#  version 6 - Bon pour l'encodage et transfert dans les répertoires mp3

set -u
set -e


encoder ()               #   fonction d'encodage avec lame
{
echo " "
echo "encodage en cours dans ===>  " "$d";         #  read
echo " "

for f in *.wav; do lame "$f" "${f%.wav}.mp3"; echo " "; done

echo " "
}

faire_le_boulot () {
echo " "
echo "la fonction faire_le_boulot démarre ";                #  read
echo "répertoire wav pour l'encodage  ===>  " "$d";   #  read

  encoder            #   fonction d'encodage avec lame

#  dest="($PWD)-mp3"

  dest="${d}-mp3"
  echo "destination des mp3 ===> " $dest;        #  read

echo "création du répertoire mp3" ;   #  read
mkdir -p "$dest"
echo "transfert des fichiers mp3 générés" ;   #  read
mv *.mp3 "$dest"
echo "transfert terminé " ;   #  read
echo " "
}

# ***********************  début du programme   *************************

# for d  in $(find  ~/Bureau/essai-script-encoder -type d); do  

 
for d  in $(find $PWD -type d); do           # cherche le chemin d'un répertoire (wav) dans le répertoire courant

    cd "$d"         # se met dans le répertoire trouvé
 
  echo " "
  echo "répertoire wav suivant trouvé  ===>  " "$d"
  echo " "
  echo "lancer l'encodage du répertoire suivant (fonction faire_le_boulot)"; read
 
 faire_le_boulot

    cd -


done

Dernière modification par Franz (24-10-2012 19:16:43)


Vieux processeur amd sempron 3000+ cadencé à 2 Gz

Hors ligne

#12 25-10-2012 11:15:01

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : Comment faire un algorithme de bouclage sur des répertoires

Franz a écrit :

il faut mettre un fichier wav dans le répertoire principal pour que ça fonctionne sinon fermeture du terminal au début.



J'ai l'impression que tu lances ce script depuis un gestionnaire de fichiers. Le moyen le plus pratique est de lancer un terminal et de lancer ton script depuis ce terminal. De cette façon tu n'auras pas besoin de tous ces « read ». Le terminal ne se fermera pas.
Ça te permettra de voir aussi les éventuels messages d'erreurs.

Autre chose ; tu n'as pas besoin d'écrire :


echo " "
 


pour avoir une nouvelle ligne. Il suffit d'écrire :


echo
 



Et une dernière sur le style. Dans un script il est préférable d'écrire des boucles entières sur une seule ligne. Dans la fonction encoder :


for f in *.wav; do lame "$f" "${f%.wav}.mp3"; echo " "; done
 


Il est plus clair d'écrire :


for f in *.wav; do
  lame "$f"  "${f%.wav}.mp3"
done
 


Tu peux même mettre le do sur une nouvelle ligne en dessous du for.
Bon, je vais tester ton script… je te tiens au courant.

Hors ligne

#13 25-10-2012 12:06:39

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : Comment faire un algorithme de bouclage sur des répertoires

J'ai compris ce qui ne marchais pas. C'est vraiment simple.
Si tu fais l'expérience de lancer :


find "$PWD" -type d
 


find va te lister tous les répertoires contenu dans "$PWD", y compris lui même.
Et ce que tu veux c'est ne prendre en compte que les sous répertoires de "$PWD".
Pour circonvenir à ce problème deux solutions me viennent à l'esprit.
1) Dire à find de en prendre en compte que les répertoires à partir d'une profondeur de 1 (la profondeur 0 étant le répertoire de base $PWD).
pour cela il suffit de rajouter une option à find :


find $PWD -mindepth 1 -type d
 


On peut même ne traiter que les sous répertoires du premier niveau :


find $PWD -mindepth 1 -maxdepth 1 -type d
 



Une autre solution (moins bonne) est de tester si le répertoire "$d" est égale à "$PWD".
Ce qui nous donne :


for d  in $(find $PWD -type d); do
  if [ "$d" = "$PWD" ]; then
      continue
  fi
  cd "$d"
  faire_le_boulot
  cd -
done
 


« continue » dans une boucle permet de passer à la prochaine itération.

Et enfin pour tester si un fichier existe, on peut procéder ainsi :


if [ -e "nom_de_fichier" ]; then
    echo "non_de_fichier existe"
else
    echo "nom_de_fichier n'existe pas"
fi
 


Et pour tester si il y a un fichier de la *.wav dans le répertoire courant, j'utilise la fonction :


file_exists ()
{
  if [ -e "$1" ]; then
     return 0
  else
    return 1
 fi
}
 


Remarques bien que pour le shell la valeur vraie est 0, et toutes autres valeurs est fausses !
Elle s'utilise comme ceci :


if file_exists *.wav;  then
  # traitement quand au moins un fichier .wav est présent
  …
fi
 


ou comme ceci :


if ! file_exists *.wav; then
  # traitement quand aucun fichier .wav n'est présent
  …
fi
 


le ! (point d'exclamation) permet d'inverser la valeur vraie en faux, et vice versa.
Voilà, tu as tout les ingrédients nécessaires.

Hors ligne

#14 25-10-2012 18:20:32

Franz
Membre
Distrib. : Squeeze
Noyau : 2.6.32-5-686
(G)UI : Gnome 2.30.2
Inscription : 08-05-2012

Re : Comment faire un algorithme de bouclage sur des répertoires

Salut enicar smile

Je suis confus de voir à quel point tu te décarcasses pour mon script. Un grand merci  !  smile

J'avais passé toute la journée à résoudre les problèmes et j'ai tout de même trouvé les solutions en rusant un peu, ça fonctionne bien mais j'ai laissé les read pour regarder le déroulement.


En tout cas j'aurais été au moins deux fois plus vite si j'avais vu tes dernières réponses car c'est ce que je cherchais à résoudre. Entre autre ce -mindepth et les syntaxes que je mets un temps fou à dénicher et comprendre sur le net.

Je vais étudier tout ça pour que ce soit un acquis profitable pour l'avenir.


Ce que je ferai c'est conserver celui que j'ai péniblement fait car j'en ai un besoin urgent (c'est pour mon boulot) et je le remodèlerai complètement avec toutes les propositions que tu as faites. Je le posterai une fois fini.


Je poste quand même le mien opérationnel bien qu'il ne soit pas très élégant et lourd. Ne rigolez pas trop à mes dépends bien que ça puisse servir en cas de déprime lol

#! /bin/bash

# version 4 - Bon pour chercher et afficher le chemin des répertoires wav et ceux des mp3 encodés (nom + mp3)
#  version 5 - Bon pour créer les répertoires mp3
#  version 6 - Bon pour l'encodage et transfert dans les répertoires mp3
#  version 7 - version d'essai de if exist pour les répertoires sans fichiers wav. Essais test si wav existe dans répertoire.
#  version 8 - version qui fonctionne bien mais garde les read pour l'instant au cas oû

# ******************************************************************************************************
# *****************   lancer le script dans le répertoire principal    *********************************

set -u
set -e


encoder ()               #   fonction d'encodage avec lame
{
echo " "
echo "encodage en cours dans ===>  " "$d";         #  read
echo " "

for f in *.wav; do lame "$f" "${f%.wav}.mp3"; echo " "; done

echo " "
}

faire_le_boulot () {
echo " "
echo "la fonction faire_le_boulot démarre ";                #  read
echo "répertoire wav pour l'encodage  ===>  " "$d";   #  read

  encoder            #   fonction d'encodage avec lame

#  dest="($PWD)-mp3"

  dest="${d}-mp3"
  echo -n "le repertoire mp3 va être créé dans  ===> "; dirname "$dest" ;         #  read

echo -n "création du répertoire " ; basename "$dest" ;  #  read
mkdir -p "$dest"
echo -n "transfert des fichiers mp3 générés dans "; basename "$dest" ;   #  read
mv *.mp3 "$dest"
echo "transfert terminé " ;   #  read
echo " "
}

# ***********************  début du programme   *************************

for d  in $(find $PWD   -mindepth 1 -type d); do           # cherche le chemin d'un répertoire (wav) dans les sous-répertoires de celui courant



    cd "$d"         # se met dans le répertoire trouvé

 
  echo " "
  echo "répertoire wav suivant trouvé  ===>  " "$d"
  echo " "
  echo "lancer l'encodage du répertoire suivant (fonction faire_le_boulot)";  read

for w in *.*; do
 
  nom_wav="$w"; echo -n "nom du fichier  " $nom_wav;  
  extension=${nom_wav##*.}; echo "  ===> " $extension;         #   read

done
read


if [ "$extension" = "wav" ]             # Vérifie qu'un fichier wav existe.
  then 
 #  ok_wav=true      

  faire_le_boulot

  beep -f 800 -n -f 800 -n -f 800

else
 #   ok_wav=false
    echo "aucun fichier wav trouvé dans le répertoire ."; echo
    continue                # Au suivant.
fi

cd -

done

beep -f 800 -n -f 800 -n -f 800
echo -n "encodage des répertoires terminés ";
read
 



Bonne soirée à tous . smile

Dernière modification par Franz (30-10-2012 11:24:01)


Vieux processeur amd sempron 3000+ cadencé à 2 Gz

Hors ligne

#15 25-10-2012 19:18:58

enicar
Membre
Lieu : pas ici
Distrib. : sid
Noyau : Linux 6.5.3
(G)UI : openbox
Inscription : 26-08-2010

Re : Comment faire un algorithme de bouclage sur des répertoires

Franz a écrit :

Je suis confus de voir à quel point tu te décarcasses pour mon script. Un grand merci  !


Je t'en prie. C'est intéressant de faire découvrir la programmation en shell à un débutant, donc ne t'inquiète pas pour moi.

Aussi, j'ai réorganisé ton script pour y voir plus clair, tu peux récupérer celui-ci ici :
wav2mp3.bash
wav2mp3.bash

J'ai pris la liberté de supprimer la plupart des commentaires et j'ai modifié quelques petites choses. Parmi celles-ci j'ai organisé ton script pour n'avoir qu'une seule commande par ligne. C'est plus facile à lire.

J'en arrive au point le plus important. Pour détecter si tu as un fichier avec l'extension .wav ta méthode n'est pas la bonne.
En effet, tu parcours tous les fichiers de la forme *.* est tu prend leur extension. Et tu positionnes la variable $extension sur l'extension trouvé. Mais si il y avait dans l'un de tes répertoires un fichier qui n'aurait pas l'extension .wav et qu'il soit traité en dernier, les fichiers .wav de ce répertoire ne seraient pas traités…
Je te propose donc la méthode suivante qui consiste à sortir de la première boucle dès que tu détecte  un fichier .wav.
Voilà, tu as maintenant plusieurs façons de résoudre le problème qui consiste à savoir s'il y a des fichiers .wav ou pas.


wav_ok=0
for w in *.*; do
  nom_wav="$w"
        echo -n "nom du fichier  $nom_wav"
  extension=${nom_wav##*.}
        echo "  ===> $extension"
        if [ "$extension" = "wav" ]; then
             wav_ok=1
             break   # on sort de la boucle for
        fi
done
 


Donc à la sortie de cette boucle la variable $wav_ok vaut 1 si il existe un fichier .wav dans le répertoire. Et donc la suite est :


if [ "$wav_ok" = "1" ]; then
  faire_le_boulot
  beep -f 800 -n -f 800 -n -f 800
else
   echo "aucun fichier wav trouvé dans le répertoire ."
   echo
fi
 


Remarques que j'ai supprimé le continue que tu avais mis. Il est inutile et peut même source de problème (car le « cd - » n'est pas exécuté, ce qui  ne pose pas de problèmes dans ton cas car les répertoires sont en absolus). Tu peux adopter celle qui te convient le mieux smile

Dernière modification par enicar (26-10-2012 11:03:43)

Hors ligne

Pied de page des forums