IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

[Script Shell] Sortie standard


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Février 2011
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 21
    Par défaut [Script Shell] Sortie standard
    Bonjour,
    Je souhaiterais, à partir d'une sortie standard, récupérer seulement les informations qui m’intéressent pour les mettre dans un fichier log.txt

    En effet j'ai mon script essai.sh:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #!/bin/sh
     
    ffmpeg -i perte.avi -vf blackdetect=d=1:pic_th=0.70:pix_th=0.10 -an -f null -
    echo Analyse fichier avi 1 terminee
    ffmpeg -i test.avi -vf blackdetect=d=1:pic_th=0.70:pix_th=0.10 -an -f null - 
    echo Analyse fichier avi 2 terminee
    ffmpeg -i perte3.avi -vf blackdetect=d=1:pic_th=0.70:pix_th=0.10 -an -f null - 
    echo Analyse fichier avi 3 terminee
    Une partie de la sortie mon terminal est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Stream #0:1: Audio: mp2 (P[0][0][0] / 0x0050), 32000 Hz, 2 channels, s16, 64 kb/s
    [buffer @ 0xa9af260] w:704 h:576 pixfmt:yuv420p tb:1/1000000 sar:1/1 sws_param:
    [blackdetect @ 0xa9a31e0] black_min_duration:1 pixel_black_th:0.100000 pixel_black_th_i:37 picture_black_ratio_th:0.700000
    Output #0, null, to 'pipe:':
      Metadata:
        encoder         : Lavf54.2.100
        Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 704x576 [SAR 1:1 DAR 11:9], q=2-31, 200 kb/s, 90k tbn, 12.50 tbc
    Stream mapping:
      Stream #0:0 -> #0:0 (mpeg4 -> rawvideo)
    Press [q] to stop, [?] for help
    black_start:1083.48 black_end:1203.81 black_duration:120.325
    bitrate=   0.0kbits/s dup=1177 drop=0    
    frame=46651 fps=522 q=0.0 Lsize=       0kB time=01:02:12.22 bitrate=   0.0kbits/s dup=1404 drop=0    
    video:0kB audio:0kB global headers:0kB muxing overhead -nan%
    En rouge les informations que je souhaiterais extraire pour chaque fichier video. (et mettre ces informations dans un fichier texte log.txt)

    Je ne sais pas si c'est possible de faire ça en 1 seul script essai.sh (qui exécuterait les commandes puis lirait la sortie standard et récupérerait les informations qui m'intéressent pour les mettre dans un fichier txt)

    Merci pour votre aide!

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Par défaut
    Comme tu ne donnes aucune indication quant au critère de sélection de la ligne en rouge, je supposerai que c'est parce qu'elle commence par "black_start".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    essai.sh | egrep '^black_start' > log.txt
    )jack(

  3. #3
    Membre averti
    Inscrit en
    Février 2011
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 21
    Par défaut
    Merci Jack,
    en effet j'ai pas beaucoup donné d'information sur cette ligne..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    black_start:1083.48 black_end:1203.81 black_duration:120.325
    Effectivement, je voulais extraire cette ligne mais plus précisément la valeur de black_start, black_end et de black_duration.

    J'ai donc utilisé le code suivant pour extraire uniquement les nombres:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/bin/sh
     
    ResuStart=`grep "black_start" out.txt` 
    ResuStart="${ResuStart##*black_start:}"
    ResuStart="${ResuStart%black_end*}"
    echo "Debut: $ResuStart" > resu.txt
     
    ResuEnd=`grep "black_end" out.txt` 
    ResuEnd="${ResuEnd##*black_end:}"
    ResuEnd="${ResuEnd%black_duration*}"
    echo "Fin: $ResuEnd" >> resu.txt
     
    ResuDuration=`grep "black_duration" out.txt` 
    ResuDuration="${ResuDuration##*black_duration:}"
    echo "Duree: $ResuDuration" >> resu.txt
    Ce qui me donne dans le fichier resu.txt :
    Debut: 720
    Fin: 840.083
    Duree: 120.083


    Mais j'ai un nouveau problème
    En effet je souhaiterais transformer les secondes (720sec, 840.083sec, 120.083sec) en minute seconde, jusque la rien de bien compliqué mais j'ai du mal avec les entiers/float

    J'ai ça qui fonctionne pour les entiers:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #!/bin/sh
     
    prMin=60
     
    ResuStart=`grep "black_start" out.txt` 
    ResuStart="${ResuStart##*black_start:}"
    ResuStart="${ResuStart%black_end*}"
    echo "$(($ResuStart / $prMin)) min $(($ResuStart % $prMin)) sec"  > result.txt
     
    ResuEnd=`grep "black_end" out.txt` 
    ResuEnd="${ResuEnd##*black_end:}"
    ResuEnd="${ResuEnd%black_duration*}"
    echo "$(($ResuEnd / $prMin)) min $(($ResuEnd % $prMin)) sec"  >> result.txt
     
    ResuDuration=`grep "black_duration" out.txt` 
    ResuDuration="${ResuDuration##*black_duration:}"
    echo "$(($ResuDuration / $prMin)) min $(($ResuDuration % $prMin)) sec"  >> result.txt
    Mais pour les float j'ai l'erreur:
    ./essai.sh: 13: arithmetic expression: expecting EOF: "840.083 / 60"

    Je sais pas comment faire pour éviter ça?!

    Merci

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Par défaut
    Citation Envoyé par LsMarx Voir le message
    Mais j'ai un nouveau problème
    En effet je souhaiterais transformer les secondes (720sec, 840.083sec, 120.083sec) en minute seconde, jusque la rien de bien compliqué mais j'ai du mal avec les entiers/float

    J'ai ça qui fonctionne pour les entiers:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #!/bin/sh
     
    prMin=60
     
    ResuStart=`grep "black_start" out.txt` 
    ResuStart="${ResuStart##*black_start:}"
    ResuStart="${ResuStart%black_end*}"
    echo "$(($ResuStart / $prMin)) min $(($ResuStart % $prMin)) sec"  > result.txt
     
    ResuEnd=`grep "black_end" out.txt` 
    ResuEnd="${ResuEnd##*black_end:}"
    ResuEnd="${ResuEnd%black_duration*}"
    echo "$(($ResuEnd / $prMin)) min $(($ResuEnd % $prMin)) sec"  >> result.txt
     
    ResuDuration=`grep "black_duration" out.txt` 
    ResuDuration="${ResuDuration##*black_duration:}"
    echo "$(($ResuDuration / $prMin)) min $(($ResuDuration % $prMin)) sec"  >> result.txt
    Mais pour les float j'ai l'erreur:
    ./essai.sh: 13: arithmetic expression: expecting EOF: "840.083 / 60"

    Je sais pas comment faire pour éviter ça?!

    Merci
    un grand classique (voir FAQ)!


    L'expression $((ResuDuration / prMin)) (où les '$' sont optionnels devant les variables) ne sait traiter que les entiers!

    Tu peux soit arrondir les flottants (supprimer ce qui suit le "."), soit utiliser un outil comme 'bc', par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo "scale=2; $ResuDuration / $prMin" | bc -l
    ou bien ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo $(echo "$ResuStart / $prMin" | bc) min $(echo "$ResuStart % $prMin" | bc) sec  > result.txt
    HTH
    )jack(

  5. #5
    Membre éprouvé Avatar de Levi59
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2011
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2011
    Messages : 58
    Par défaut
    Citation Envoyé par jack-ft
    Tu peux soit arrondir les flottants (supprimer ce qui suit le "."), soit utiliser un outil comme 'bc', par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo "scale=2; $ResuDuration / $prMin" | bc -l
    ou bien ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo $(echo "$ResuStart / $prMin" | bc) min $(echo "$ResuStart % $prMin" | bc) sec  > result.txt
    HTH
    )jack(
    J'aurais gardé le fond mais changé la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bc -l <<<"scale=2; $ResuStart / $prMin"
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo $(bc <<<"$ResuStart / $prMin") min $(bc <<<"$ResuStart % $prMin") sec > result.txt
    Cela ne change rien au résultat par contre

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Par défaut
    Citation Envoyé par Levi59 Voir le message
    J'aurais gardé le fond mais changé la forme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bc -l <<<"scale=2; $ResuStart / $prMin"
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    echo $(bc <<<"$ResuStart / $prMin") min $(bc <<<"$ResuStart % $prMin") sec > result.txt
    Cela ne change rien au résultat par contre
    Effectivement, le "herestring" allège considérablement la forme...

    ATTENTION, ça ne change rien au résultat si on est en bash.

    En revanche, ça change quand même un tout petit peu le résultat si on est en ksh:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ bc <<< '1 + 1'    
    ksh: syntax error: `< ' unexpected

  7. #7
    Membre averti
    Inscrit en
    Février 2011
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 21
    Par défaut
    Merci pour vos réponses, rapides et efficaces!

    J'ai modifié mon script shell, et je fais face à un nouveau problème, une fois de plus!
    Pour l'instant le script me permet d'analyser tout un dossier de fichier .avi et d'indiquer sur le terminal le nom du fichier, et si suite à l'analyse il y a une blackframe (affiche PERTE) ou non (affiche OK).
    Ce script écrit également dans un fichier result.txt le Debut, la Durée et la Fin du blackframe selon le fichier analysé.

    Le souci c'est que le script ne gère pas les cas ou il y a plusieurs blackframe dans un fichier .avi

    En effet, la ligne rouge ci dessous apparait autant de fois qu'il y a de blackframe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     Stream #0:0 -> #0:0 (mpeg4 -> rawvideo)
    Press [q] to stop, [?] for help
    black_start:1083.48 black_end:1203.81 black_duration:120.325
    bitrate=   0.0kbits/s dup=1177 drop=0
    Voici mon script:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    #!/bin/sh
     
    get_info() 
    {
    prMin=60
    present=`grep "black_start" RESULTAT/output.txt` 
     
    if [ $present ] 
    then
     
    	NomFichier=`grep "Input" RESULTAT/output.txt` 
    	NomFichier="${NomFichier##*from '}"
    	NomFichier="${NomFichier%'*}"
     
    	echo "PERTES"
    	echo $NomFichier "\t" "PERTES" >> RESULTAT/result.txt
     
    ResuDuration=`grep "black_duration" RESULTAT/output.txt` 
    ResuDuration="${ResuDuration##*black_duration:}"
     
    echo "\n"DUREE "\t" $(echo "scale = 0; $ResuDuration/$prMin" | bc) min $(echo "$ResuDuration % $prMin" | bc | cut -d'.' -f1) sec $(echo "$ResuDuration % $prMin" | bc | cut -d'.' -f2) ms>> RESULTAT/result.txt
     
    ResuStart=`grep "black_start" RESULTAT/output.txt` 
    ResuStart="${ResuStart##*black_start:}"
    ResuStart="${ResuStart%black_end*}"
     
    echo DEBUT "\t" $(echo "scale = 0; $ResuStart/$prMin" | bc) min $(echo "$ResuStart % $prMin" | bc | cut -d'.' -f1) sec $(echo "$ResuStart % $prMin" | bc | cut -d'.' -f2) ms>> RESULTAT/result.txt 
     
    ResuEnd=`grep "black_end" RESULTAT/output.txt` 
    ResuEnd="${ResuEnd##*black_end:}"
    ResuEnd="${ResuEnd%black_duration*}"
     
    echo FIN "\t" $(echo "scale = 0; $ResuEnd/$prMin" | bc) min $(echo "$ResuEnd % $prMin" | bc | cut -d'.' -f1) sec $(echo "$ResuEnd % $prMin" | bc | cut -d'.' -f2) ms"\n">> RESULTAT/result.txt
     
    else
     
    	echo "OK"
    	echo $NomFichier "\t" "OK" >> RESULTAT/result.txt
    fi
    }
     
    clear
    cd rec_pertes
    mkdir RESULTAT
    ls > RESULTAT/liste.txt
    rm -f RESULTAT/result.txt
     
    echo "\n"
    echo "#####################################################################"
    echo "##################   Analyse des fichiers videos   ##################"
    echo "#####################################################################"
    echo "\n"
    # On stocke le fichier dans le buffer 3
    exec 3<RESULTAT/liste.txt
    # On lit le buffer 3 ligne par ligne
    while read ligne 0<&3
    do
    	if [ $ligne != RESULTAT ]
    	then
    	echo "\t" "Analyse du fichier: $ligne"
    	ffmpeg -i $ligne -vf blackdetect=d=0.1:pic_th=0.70:pix_th=0.10 -an -f null - 2> RESULTAT/output.txt
    	get_info
    	fi
    done
    echo "\n"
    echo "#####################################################################"
    echo "\n"
     
    rm -f RESULTAT/liste.txt
    rm -f RESULTAT/output.txt
    J'ai pensé corriger le problème de cette manière:

    faire un while juste apres le,
    echo "PERTES"
    echo $NomFichier "\t" "PERTES" >> RESULTAT/result.txt

    La condition du while serait tant qu'il y a encore un black_start, black_end, black_duration dans output.txt

    Mais je ne vois pas comment extraire les informations de black_start, black_end.. autrement que comme j'avais fait précédemment (sachant que cette ancienne méthode récupère seulement les information du dernier blackframe)

    L'objectif serait d'avoir dans le document result.txt quelque chose comme ca:

    cam01_20120306-111001.144.avi OK
    cam01_20120306-111036.433.avi OK
    cam02_20120306-111241.460.avi PERTES

    N°1
    DUREE 0 min 21 sec 7551 ms
    DEBUT 1 min 15 sec 6756 ms
    FIN 1 min 37 sec 4307 ms

    N°2
    DUREE 0 min 7 sec 1500 ms
    DEBUT 4 min 2 sec 9750 ms
    FIN 4 min 10 sec 1250 ms

    ...

    cam02_20120306-111441.458.avi OK


    Merci encore pour votre aide

  8. #8
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 654
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 654
    Par défaut
    Bonjour,

    je ne vais pas mettre les mains là dedans : si je commence à corriger une ligne, je vais devoir réécrire tout le script, tellement...

    je voulais juste dire que bc dispose d'une fonction pour le formatage des données (print).

    et qu'on n'utilise pas ls dans les scripts ! on fait une boucle for sur le déveleoppement des chemins :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for f in rec-pertes/*; do :peuimporte; done
    qu'on ne fait pas trois grep, pour récupérer trois élément d'une même ligne

    ...
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

Discussions similaires

  1. Réponses: 4
    Dernier message: 13/05/2014, 14h49
  2. Redirection sortie standard pour script bash executé en crontab
    Par natha_poup dans le forum Shell et commandes GNU
    Réponses: 7
    Dernier message: 06/03/2014, 13h03
  3. [Batch] Script Batch et sortie standard
    Par EtudiantFr dans le forum Scripts/Batch
    Réponses: 1
    Dernier message: 25/02/2013, 23h23
  4. Redirection de sortie standard dans un script bash
    Par redvivi dans le forum Linux
    Réponses: 4
    Dernier message: 07/09/2008, 21h19
  5. Réponses: 6
    Dernier message: 12/04/2006, 14h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo