#1 Le 26/09/2011, à 17:21
- wolf85kunst
Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
Bonjour,
je cherche à réaliser un petit script qui me génère un listing de mes vidéos et qui me récupère certaines informations. Le tout sauvegardé dans un fichier texte. La structure du fichier texte généré devra alors ressembler à ça :
les valeurs sont séparé par ":" (séparateur).
ma_video.avi:chemin_absolu:resolution_de_la_video:poid_en_megaoctets
Je possède une bonne base de travail grâce aux commandes suivantes :
# Pour obtenir le nom du fichier
find /home/ -type f \( -iname "*.avi" -o -iname "*.mkv" -o -iname "*.mpeg" \) -exec basename {} \;
# pour obtenir des informations sur la vidéo
mplayer -ao dummy -vo dummy -identify ma_video.avi
Mais j'ai du mal à organiser l’algorithme. De plus, comment lancer plusieurs commandes imbriqué dans "find" grâce à exec ?
Quel serait le meilleur fil pour écrire ce script bash ?
Je vous remercie.
Dernière modification par wolf85kunst (Le 28/09/2011, à 18:55)
Les raisonnables ont duré, les passionnés ont vécu.
-- 10.04 Lucid Lynx --
Hors ligne
#2 Le 26/09/2011, à 18:51
- Levi59
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
Ceci devrait t'aider!
> fichier.log # vider le fichier de log. Supprimer la ligne pour conserver le contenu.
while read
do
Name=${REPLY##*/}
Poids=$(stat -c '%s' "${REPLY}") ## en octets
Poids=$(echo "scale=3;$Poids/1048576" | bc) ## en Mega octets
Size=$(mplayer "$REPLY" -vo null -ao null -frames 0 -identify 2>/dev/null | egrep -m2 '^ID_VIDEO_(WIDTH|HEIGHT)')
Width=$(echo ${size#*=} | cut -d" " -f 1)
Height=${Size##*=}
Resolution="${Width}x${Height}"
echo "$Name:$(dirname $Name)/$Name:$Resolution:$Poids" >> fichier.log # À toi de voir où mettre le fichier.
done < <(find /home/ -type f \( -iname "*.avi" -o -iname "*.mkv" -o -iname "*.mpeg" \))
Edit Correction
Dernière modification par Levi59 (Le 27/09/2011, à 14:40)
Hors ligne
#3 Le 27/09/2011, à 12:17
- Levi59
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
J'ai effectué une petite correction (utilisation de $REPLY au lieu de $Name)
Dernière modification par Levi59 (Le 27/09/2011, à 12:18)
Hors ligne
#4 Le 27/09/2011, à 14:12
- Postmortem
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
Salut,
Une petite suggestion pour obtenir la taille en enlevant un pipe.
Poids=$(stat -c '%s' "${REPLY}")
Et une petite correction sinon il n'y aura que le dernier fichier dans le listing (remplacement de > par >> ) :
echo "$Name:$(dirname $Name)/$Name:$Resolution:$Poids" >> fichier.log
Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »
Hors ligne
#5 Le 27/09/2011, à 14:35
- Levi59
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
Oups! effectivement, j'avais mal redirigé! ^^
Par contre merci pour stat, je ne connaissais pas.
Hors ligne
#6 Le 27/09/2011, à 14:48
- Postmortem
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
De rien, je l'ai découvert sur ce forum !
Un autre truc que j'ai appris ici, mais là c'est pour mettre "ceinture et bretelles" ; faire la boucle ainsi :
while read -rd ''
do
...
done < <( find /home/ -type f \( -iname "*.avi" -o -iname "*.mkv" -o -iname "*.mpeg" \) -print0 )
Ça permet de traiter correctement avec read les \ qui pourraient être dans les noms de fichiers (sinon, ils sont supprimés) et aussi de bien traiter les noms de fichiers qui contiendraient un retour à la ligne.
Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »
Hors ligne
#7 Le 27/09/2011, à 19:13
- wolf85kunst
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
Bonjour à tous,
Merci beaucoup pour vos réponses.
Je réalise de temps en temps des scripts bash, mais là je vous avouerai que j'ai un peu de mal à déchiffrer vos productions.
Analyse du script :
- Une boucle "while" reste le moyen le plus adapté pour réaliser des actions à chaque réponse de la commande "find". On lit chaque résultat de la commande find et on réalise les actions à l'intérieur de la boucle.
- Cependant je ne comprend pas les deux "<" après le "done" :
done < <(find.......
Pourquoi entourer la fonction "find" de parenthèses ?
- Mais que veut dire cette ligne ? Quelle valeur prend la variable "Name" ? A quoi servent les symboles "##*/"
]Name=${REPLY##*/}
- Quel est la différence pour le shell entre
$(.....)
# et
${.....}
- Enfin, on attribue une valeur à la variable "Height" :
Height=${Size##*=}
...Mais que signifie "Size##*= ?
Merci beaucoup pour votre investissement.
Les raisonnables ont duré, les passionnés ont vécu.
-- 10.04 Lucid Lynx --
Hors ligne
#8 Le 27/09/2011, à 19:56
- Levi59
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
Bonjour à tous,
Merci beaucoup pour vos réponses.
Je réalise de temps en temps des scripts bash, mais là je vous avouerai que j'ai un peu de mal à déchiffrer vos productions.
De rien! ^^
Analyse du script :
- Une boucle "while" reste le moyen le plus adapté pour réaliser des actions à chaque réponse de la commande "find". On lit chaque résultat de la commande find et on réalise les actions à l'intérieur de la boucle.- Cependant je ne comprend pas les deux "<" après le "done" :
done < <(find.......
Pourquoi entourer la fonction "find" de parenthèses ?
Il s'agit d'une redirection du resultat de la commande find dans la boucle while do ...done. La redirection prend plusieurs forme selon le type de "données" redirigées.
Si c'est un fichier, un simple "<" suffit, si c'est une commande, il faut indiquer qu'il s'agit d'une commande à effectuer et on la place donc entre "<(commande)" en plus de la redirection normale.
- Mais que veut dire cette ligne ? Quelle valeur prend la variable "Name" ? A quoi servent les symboles "##*/"
]Name=${REPLY##*/}
C'est une substitution... En gros ici ça veut dire :
Supprimer toute la chaine jusqu'au dernier slash soit jusqu'au nom de fichier.
ex
~/bla/blo/fichier.txt => fichier.txt
./truc/machin/fichier.txt => fichier.txt
/chemin/vers/fichier.txt => fichier.txt
- Quel est la différence pour le shell entre
$(.....) # et ${.....}
$(commande) indique une commande à effectuer
${variable} indique une variable et permet de s'assurer que celle ci est correctement interprétée. Cela permet aussi d'utiliser les substitutions
- Enfin, on attribue une valeur à la variable "Height" :
Height=${Size##*=}
...Mais que signifie "Size##*= ?
Idem que précédement mais avec le symbole "="
La variable Size est de la forme "Weight=123 Height=456" et l'ecriture supprime donc tout pour donner "456"
Hors ligne
#9 Le 27/09/2011, à 20:06
- Postmortem
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
Salut,
Pour la boucle while, en général, on fait comme ça :
while read ligne
do
ici on met des commandes exploitant la variable $ligne
done < un-fichier
Donc ton cas, on exploite pas un fichier mais le résultat d'une commande donc, on utilise la syntaxe <(commande)
while read ligne
do
ici on met des commandes exploitant la variable $ligne
done < <(commande)
Il faut bien mettre une espace entre < (qui indique une redirection d'entrée) et <(commande)
De plus, si on ne précise pas de nom de variable après read, la variable REPLY est utilisée.
${ma_var} : est remplacé par la valeur de la variable ma_var
$(commande) : est remplacé par le résultat de la commande, par exemple :
var=$(ls /tmp)
La variable var contiendra la liste des fichiers et dossiers se trouvant dans /tmp.
Dernière modification par Postmortem (Le 27/09/2011, à 20:31)
Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »
Hors ligne
#10 Le 27/09/2011, à 20:50
- Postmortem
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
${ma_var#*-} : est remplacé par la valeur de ma_var à laquelle on retire la plus courte partie correspondant à *- au début (avec 2 #, ça serait la plus longue partie).
${ma_var%-*} : la meme chose que ci-dessus mais à la fin.
Quelques exemples :
$ ma_var="ta-te-ti-to"
$ echo ${ma_var#*-}
te-ti-to
$ echo ${ma_var##*-}
to
$ echo ${ma_var%-*}
ta-te-ti
$ echo ${ma_var%%-*}
ta
$ echo ${ma_var%%o}
ta-te-ti-t
$ echo ${ma_var%o}
ta-te-ti-t
Plus d'infos sur tout ça dans man bash
Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »
Hors ligne
#11 Le 27/09/2011, à 21:15
- wolf85kunst
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
Merci à vous deux pour vos réponses.
@Levi59: Merci pour l'explication générale du script
@posmortem: Merci pour ce petit cours sur les substitutions. Je ne connaissais absolument pas cette fonctionnalité et aurais eu tendance à utiliser des filtres avec "(e)grep" et "sed" ! D'ailleurs quels seraient les avantages de la subsitution grace à ${xxx} face à ces dernières commandes ?
Aussi, j'ai fais quelques recherches rapides sur la substitution. Ce site explique assez bien le principe la-substitution
On y trouve cette commande en particulier
chaineZ='abcABC123ABCabc'
echo ${chaineZ/#abc/XYZ}
# --> XYZABC123ABCabc
Cependant ils utilisent le slash ('/'). chaine, sous-chaine, remplacement. Pourquoi ?
D'autre part, j'ai pu m'amuser avec votre script. Le résultat est presQUE à la hauteur de mes espérences
Voici ce que me retourne la fonction dans le fichier de log :
[...]
:./00244=48975=44845=37652.avi:800x592:2282780
:./00244=49290=44931=45024.avi:800x592:1828520
:./00244=45115=45115=45115.avi:800x592:1191708
:./00244=44829=44829=44829.avi:800x592:3453662
:./00244=37618=37618=37618.avi:800x592:1120864
:./00244=49327=37666=37654.avi:800x592:3472408
:./00244=49182=37653=44809.avi:800x592:2147830
:./00244=49040=44856=37654.avi:800x592:1034514
:./00244=49358=45239=45338.avi:800x592:1535450
:./mavideo.avi:492x360:3337223
:./mavideo2.avi:854x480:88561190
:./mavideo3.avi:854x480:30056853
:./mavideo4.avi:640x480:27137050
:./mavideo5.avi:854x474:37252937
:./mavideo6.avi:1920x1080:242007056
:./mavideo7.avi:854x480:39358090
[...]
- On remarque dans les premières lignes un résultat étrange. D'où viennent ces retours ?
- Les 7 dernières lignes ont déjà meilleur mine. Il s'agit bien de mes fichiers vidéos. Mais :
--> Comme toutes les lignes générés, elles commencent par ":" . Ce qui veut dire que la variable "Names" ne s'affiche pas correctement.
--> De même pour le "dirname" appliqué à cette même variable, car la deuxième partie commence par "./mavideo.avi".
--> J'ai vérifié, l'affichage du "poids" de la vidéo (dernière partie d'une ligne de retour) est en octets et non en mégaoctets.
Comment corriger ces problèmes ?
Merci pour tout.
Dernière modification par wolf85kunst (Le 27/09/2011, à 21:18)
Les raisonnables ont duré, les passionnés ont vécu.
-- 10.04 Lucid Lynx --
Hors ligne
#12 Le 27/09/2011, à 22:35
- Postmortem
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
@Levi59 : désolé, je t'ai répété, j'avais pas vu que tu avais répondu !
@posmortem: Merci pour ce petit cours sur les substitutions. Je ne connaissais absolument pas cette fonctionnalité et aurais eu tendance à utiliser des filtres avec "(e)grep" et "sed" ! D'ailleurs quels seraient les avantages de la subsitution grace à ${xxx} face à ces dernières commandes ?
Je dirais que l'avantage est d'éviter de faire appel à des commandes externes. C'est bash lui-meme qui fait les substitutions.
Mais c'est bien pour les substitutions simples, si c'est plus complexe, il faut faire appel à ces commandes.
Cependant ils utilisent le slash ('/'). chaine, sous-chaine, remplacement. Pourquoi ?
${ma_var#texte} permet de supprimer "texte" au début de la valeur de ma_var
${ma_var/texte/remplacement} permet de remplacer la première occurrence de "texte" par "remplacement"
${ma_var//texte/remplacement} permet de remplacer toutes les occurrences de "texte" par "remplacement"
${ma_var/#texte/remplacement} permet de remplacer "texte" par "remplacement" si "texte" est au début de la valeur de ma_var
Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »
Hors ligne
#13 Le 27/09/2011, à 22:59
- Postmortem
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
De même pour le "dirname" appliqué à cette même variable, car la deuxième partie commence par "./mavideo.avi".
Je pense que tu as fait un find de ce type, find . -type f ....., non ?!?
Si c'est le cas c'est normal que ça donne "./mavideo.avi" car dirname ./fichier renvoie . (point)
Si tu veux un chemin absolu, il faut mettre un chemin absolu dans find
Comme toutes les lignes générés, elles commencent par ":" . Ce qui veut dire que la variable "Names" ne s'affiche pas correctement.
N'as tu pas fait une erreur dans le nom de ta variable ??
Tu pourrais nous poster ton script pour qu'on regarde sinon.
Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »
Hors ligne
#14 Le 27/09/2011, à 23:06
- Levi59
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
Alors, je n'avais honnêtement pas testé mais je croyais que dirname donnait toujours le chemin absolu.
J'ai installé mplayer et j'ai repéré un probleme dans la variable size. j'ai donc corrigé avec une boucle for...done.
Pour corriger l'erreur de chemin, on peut remplacer $(dirname "$Name") par ${REPLY%/*} dans la ligne renvoyé dans le log.
Pour le problème de la variable $Name non affichée, c'est bizarre car chez moi ça marche.
Peux tu reprendre ce code? (j'ai ajouté les corrections précédentes)
#!/bin/bash
cd
> fichier.log # vider le fichier de log. Supprimer la ligne pour conserver le contenu.
while read
do
echo $REPLY
Name=${REPLY##*/}
Poids=$(stat -c '%s' "${REPLY}") ## en octets
Poids=$(echo "scale=3;${Poids}/1048576" | bc) ## en Mega octets
for i in $(mplayer "$REPLY" -vo null -ao null -frames 0 -identify 2>/dev/null | egrep -m2 '^ID_VIDEO_(WIDTH|HEIGHT)')
do
[[ $i =~ WIDTH ]] && Width=${i#*=}
[[ $i =~ HEIGHT ]] && Height=${i#*=}
done
Resolution="${Width}x${Height}"
echo "$Name:${REPLY%/*}/$Name:$Resolution:$Poids" >> fichier.log # À toi de voir où mettre le fichier.
done < <(find /media/Vidéos/ -type f \( -iname "*.avi" -o -iname "*.mkv" -o -iname "*.mpeg" \))
ensuite en console lance :
bash -x ./lescript.sh >> debug.log
Et copie-colle le contenu de debug.log (c'est une commande de debug pour voir comment tourne le script.
Dernière modification par Levi59 (Le 28/09/2011, à 00:32)
Hors ligne
#15 Le 28/09/2011, à 18:54
- wolf85kunst
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
Bonjour.
Merci à tous deux.
Je pense que tu as fait un find de ce type, find . -type f ....., non ?!?
Effectivement, j'ai voulu affiner un peu la recherche.
Comme toutes les lignes générés, elles commencent par ":" . Ce qui veut dire que la variable "Names" ne s'affiche pas correctement.
Effectivement j'ai voulu mettre mes variables perso. J'avais oublié de modifié la variable "Name" à tous les endroits.
Des lignes étranges :
:./00244=49290=44931=45024.avi:800x592:1828520
:./00244=45115=45115=45115.avi:800x592:1191708
:./00244=44829=44829=44829.avi:800x592:3453662
:./00244=37618=37618=37618.avi:800x592:1120864
:./00244=49327=37666=37654.avi:800x592:3472408
Il s'agissait tout simplement de mon écran de veille présent dans /home/user/.electricsheep. Très joli screensaver au passage
@Levi59 : Merci pour ton investissement et ton script maison qui me permetra d'aller plus loin dans le développement shell bash Linux.
@Tous deux : Merci pour vos réponses
Mon script fonctionne désormais correctement.
J’espère vous recroiser sur le forum Ubuntu-fr.
Bonne fin de journée. Ce sujet est maintenant résolu.
Dernière modification par wolf85kunst (Le 28/09/2011, à 18:57)
Les raisonnables ont duré, les passionnés ont vécu.
-- 10.04 Lucid Lynx --
Hors ligne
#16 Le 28/09/2011, à 22:09
- Levi59
Re : Lister ses vidéos dans un fichier et récupérer des infos [RESOLU]
c'était un plaisir!
Hors ligne