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 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! wink

> 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 wink (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]

wolf85kunst a écrit :

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! ^^

wolf85kunst a écrit :

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.

wolf85kunst a écrit :

-  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

wolf85kunst a écrit :

- 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

wolf85kunst a écrit :

- 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 smile
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 !

wolf85kunst a écrit :

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

wolf85kunst a écrit :

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]

wolf85kunst a écrit :

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

wolf85kunst a écrit :

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.

Postmortem a écrit :

Je pense que tu as fait un find de ce type, find . -type f ....., non ?!?

Effectivement, j'ai voulu affiner un peu la recherche.

Wolf85kunst a écrit :

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 smile

@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! wink

Hors ligne