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 bash - lecture d'un fichier texte


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 14
    Par défaut Script bash - lecture d'un fichier texte
    Bonjour,
    Je suis confronté à un problème curieux. Dans un script bash dont l'objet est de découper une vidéo à l'aide de ffmpeg et de d'enregistrer les fichiers ainsi créés, je dois lire un fichier ligne par ligne et extraire de chaque ligne 3 éléments (début de la découpe, longueur de l'extrait et nom du fichier). Il s'avère que parfois pour certaines lignes, la lecture ne commence pas au début de la ligne, ce qui fait que l'extraction ne fonctionne pas correctement.

    Extrait de mon script :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    fichierD=`zenity --file-selection --title="Selectionnez un fichier"`
     
    while read enreg; do
        temps_debut=`echo $enreg | cut -d';' -f1`
        duree=`echo $enreg | cut -d';' -f2`
        nom_fichier=`echo $enreg | cut -d';' -f3`
        ffmpeg -ss $temps_debut -t $duree -i "$1" -b 4M "$nom_fichier"
    done < $fichierD
    Le fichier texte est de la forme
    00:00:03.200;00:00:03.300;falaise.avi
    00:00:13.500;00:00:04.700;grotte.avi
    00:00:26.200;00:00:03.500;arc.avi
    A titre d'exemple, sur un fichier de 25 lignes, 15 sont lues correctement. Si je supprime les lignes lues correctement, sur les 10 restantes, 8 sont lues correctement...
    Il arrive également que tout passe parfaitement.

    J'ai également remarqué que si je lance le script en ayant commenté la commande ffmpeg, la lecture se passe correctement.

    Si quelqu'un avait une idée...

    Merci de votre aide.

    Bonne soirée.

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

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

    pas facile avec un extrait de fichier qui ne semble pas contenir le motif générant une erreur dans ton script

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while IFS=';' read debut duree nom
    do
       ffmpeg -ss $debut -t $duree -i "$1" -b 4M "$nom"
    done <"$fichierD"
    cf . Comment lire/parser un fichier
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 14
    Par défaut
    Merci de cette réponse rapide. Je pensais que l'extrait, qui représente la majeure partie du script était suffisant. J'ai donc testé avec ta proposition, voici le script complet :

    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
    #!/bin/bash
     
    # verification, nom du fichier selectionne
    #zenity --info --title="Info" --text="Saisie : $1"
     
    # On verifie qu'un fichier a ete selectionne
    	if [ $# -eq 0 ]; then
    		zenity --error --title="Erreur" --text="Pour utiliser cet utilitaire, vous devez au prealable selectionner un fichier. Le script va se terminer, relancez le"
    		exit 1
    	fi
     
    #################################################
    # on choisit le fichier de donnees
    ##################################################
     
    fichierD=`zenity --file-selection --title="Selectionnez un fichier"`
     
    #########################
    # on commence la decoupe#
    #########################
     
    while IFS=';' read debut duree nom
    do
       ffmpeg -ss $debut -t $duree -i "$1" -b 4M "$nom"
    done <"$fichierD"
     
    exit 0
    avec le fichier texte suivant :
    00:00:03.200;00:00:03.300;falaise.avi
    00:00:13.500;00:00:04.700;grotte.avi
    00:00:26.200;00:00:03.500;arc.avi
    00:00:51.500;00:00:05.800;fleche.avi
    00:00:59.100;00:00:03.300;cerf.avi
    00:01:08.600;00:00:04.000;chamois.avi
    00:01:14.200;00:00:03.100;renne.avi
    00:01:19.500;00:00:03.600;rhinoceros.avi
    00:01:29.600;00:00:02.900;pointe_pointu.avi
    00:01:36.200;00:00:04.500;archeologie.avi
    00:01:43.300;00:00:03.700;anthropologie.avi
    00:01:54.100;00:00:04.300;armure.avi
    00:01:59.700;00:00:04.900;bouclier.avi
    00:02:06.700;00:00:04.300;casquemoyage.avi
    00:02:13.200;00:00:03.400;banquet.avi
    00:02:30.200;00:00:05.600;chevalier.avi
    00:02:39.700;00:00:03.400;seigneurma.avi
    00:02:55.000;00:00:03.500;serf.avi
    00:03:01.200;00:00:05.300;tournoi.avi
    00:03:09.100;00:00:04.100;rempart_muraille.avi
    00:03:20.800;00:00:03.500;tour.avi
    00:03:37.300;00:00:04.500;abbaye.avi
    00:04:07.300;00:00:04.200;cardinal.avi
    00:04:14.500;00:00:04.200;chapelle.avi
    00:04:21.000;00:00:03.300;eveque.avi
    00:04:31.300;00:00:05.000;monastere.avi
    00:04:40.000;00:00:04.600;refectoire.avi
    00:04:56.000;00:00:04.700;pelerinage.avi
    00:05:35.500;00:00:04.900;aqueduc.avi
    00:05:52.300;00:00:05.200;horloge.avi
    Il a été extrait 25 vidéos, manquent
    00:00:26.200;00:00:03.500;arc.avi
    00:03:09.100;00:00:04.100;rempart_muraille.avi
    00:04:07.300;00:00:04.200;cardinal.avi
    00:04:40.000;00:00:04.600;refectoire.avi
    00:05:35.500;00:00:04.900;aqueduc.avi
    Au second tour, en enlevant les lignes qui ont été correctement traitées, 3 lignes ont été lues.

    Lors du traitement, en faisant afficher la ligne 00:00:26.200;00:00:03.500;arc.avi (qui n'a pas été traitée correctement) on ne lit que 0:26.200;00:00:03.500;arc.avi
    Tout cela est très mystérieux.

    En tous cas, encore merci.
    Cordialement.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 652
    Par défaut

    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
     $ wc -l OmegaZ.file; while IFS=';' read debut duree nom; do echo "$((++n)) - $nom , $debut, $duree"; done < OmegaZ.file ; n=''
    30 OmegaZ.file
    1 - falaise.avi , 00:00:03.200, 00:00:03.300
    2 - grotte.avi , 00:00:13.500, 00:00:04.700
    3 - arc.avi , 00:00:26.200, 00:00:03.500
    4 - fleche.avi , 00:00:51.500, 00:00:05.800
    5 - cerf.avi , 00:00:59.100, 00:00:03.300
    6 - chamois.avi , 00:01:08.600, 00:00:04.000
    7 - renne.avi , 00:01:14.200, 00:00:03.100
    8 - rhinoceros.avi , 00:01:19.500, 00:00:03.600
    9 - pointe_pointu.avi , 00:01:29.600, 00:00:02.900
    10 - archeologie.avi , 00:01:36.200, 00:00:04.500
    11 - anthropologie.avi , 00:01:43.300, 00:00:03.700
    12 - armure.avi , 00:01:54.100, 00:00:04.300
    13 - bouclier.avi , 00:01:59.700, 00:00:04.900
    14 - casquemoyage.avi , 00:02:06.700, 00:00:04.300
    15 - banquet.avi , 00:02:13.200, 00:00:03.400
    16 - chevalier.avi , 00:02:30.200, 00:00:05.600
    17 - seigneurma.avi , 00:02:39.700, 00:00:03.400
    18 - serf.avi , 00:02:55.000, 00:00:03.500
    19 - tournoi.avi , 00:03:01.200, 00:00:05.300
    20 - rempart_muraille.avi , 00:03:09.100, 00:00:04.100
    21 - tour.avi , 00:03:20.800, 00:00:03.500
    22 - abbaye.avi , 00:03:37.300, 00:00:04.500
    23 - cardinal.avi , 00:04:07.300, 00:00:04.200
    24 - chapelle.avi , 00:04:14.500, 00:00:04.200
    25 - eveque.avi , 00:04:21.000, 00:00:03.300
    26 - monastere.avi , 00:04:31.300, 00:00:05.000
    27 - refectoire.avi , 00:04:40.000, 00:00:04.600
    28 - pelerinage.avi , 00:04:56.000, 00:00:04.700
    29 - aqueduc.avi , 00:05:35.500, 00:00:04.900
    30 - horloge.avi , 00:05:52.300, 00:00:05.200
    avec cat -A tonFichier, toutes les lignes se terminent bien par un unique $ ? ou y a-t-il des caractères en plus ?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 14
    Par défaut
    Pas de caractère en plus. Ce qui me gêne, c'est que si je retire les lignes qui fonctionnent sans rien changer au reste du fichier, on traite une partie et seulement une partie, de ce qui reste. Il faut faire plusieurs "tours" pour pouvoir tout traiter.
    J'ai testé avec plusieurs postes, mais tous sous Ubuntu 14.04, avec le même résultat, je me demande si c'est un problème d'OS.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 652
    Par défaut

    tu peux nous mettre ton fichier en pièce jointe ?

    as-tu essayé en copiant le contenu du fichier depuis le post en cours ?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 118
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 118
    Par défaut
    Salut,

    j'ai tout lu, c'est très curieux.
    On dirait que ffmpeg rend la main au script (pour donc passer à la ligne suivante) alors qu'il est en train d'écrire les trames extraites du fichier, donc peut-être petit sac de nœuds ?

    Tente de mettre un sync après la ligne ffpmeg, des fois que ça améliorerait les choses (ça risque de les ralentir un poil, par contre, mais si le résultat est bon...)

  8. #8
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 347
    Par défaut
    Bonsoir,

    Es-tu sur de nous avoir envoyé les fichiers qui posent problème (surtout celui de données) ?

    En le réduisant pour n'avoir que les lignes qui ne sont pas passées au départ, tu as peut-être corrigé le problème...

    Par exemple, le fichier DecoupeV2.txt que tu nous a fourni, a un problème sur la première ligne (il y a 3 caractères avant #!/bin/bash):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ sed -n 'l'  DecoupeV2.txt 
    \357\273\277#!/bin/bash$
    $
    # verification, nom du fichier selectionne$
    #zenity --info --title="Info" --text="Saisie : $1"$
    ....
    ....
    Et même si ffmpeg rendait la main avant de finir son traitement, je ne vois pas trop comment une seule variable (debut) peut être corrompu à moitié alors que se même ffmpeg n'utilise pas le fichier qui permet d'initialiser cette variable (en plus, même zenity la montre fausse).
    Ici, le problème est la boucle while read et surtout les données qu'on lui fourni.

  9. #9
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 14
    Par défaut
    Bonjour,

    Pour Jipété : j'ai testé en rajoutant la commande sync, effectivement ralentissement du traitement, des lignes sont toujours sautées de façon aléatoire, d'un test sur l'autre je n'ai pas le même résultat. Pour information, le ralentissement est net avec ffmpeg, imperceptible avec avconv.

    Pour Disedorgue : je te confirme que j'ai bien envoyé les fichiers à problème. Je ne comprends pas les caractères en début de texte, qui sont effectivement présents sur mon script, je les vois avec sed mais pas avec cat.

    Après de nouveaux essais ce matin, je confirme que le problème se pose avec ffmpeg, mais pas avec avconv. Cela résout le problème, mais j'aimerai bien comprendre.

    Bien cordialement.

  10. #10
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 323
    Par défaut
    Bonjour,
    ces 3 caractères "cachés" c'est de l'utf-8 avec BOM; signature plutôt courante sous windows par contre plus que rare sous linux ...

  11. #11
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 118
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 118
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Ici, le problème est la boucle while read et surtout les données qu'on lui fournit.
    Vi vi vi, sauf que si je remplace la ligne ffmpeg... par echo $debut $duree $nom ça fonctionne très bien, confirmé par

    Citation Envoyé par OmegaZ Voir le message
    Après de nouveaux essais ce matin, je confirme que le problème se pose avec ffmpeg, mais pas avec avconv.
    En prime, ce commentaire
    Citation Envoyé par OmegaZ Voir le message
    Pour Jipété : j'ai testé en rajoutant la commande sync, effectivement ralentissement du traitement, des lignes sont toujours sautées de façon aléatoire, d'un test sur l'autre je n'ai pas le même résultat. Pour information, le ralentissement est net avec ffmpeg, imperceptible avec avconv.
    me fait penser qu'il y a une embrouille de timing quelque part, liée à ffmpeg...

    OmegaZ, tu devrais systématiquement tester la valeur de retour de ta commande, genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ffmpeg...
    ret=$?
    if [ "$ret" != "0" ]; then
    	echo "Erreur ffmpeg"
    fi
    J'ai eu travaillé sur un script de sauvegarde à base de rsync qu'il a fallu que je blinde de lignes sync; sync; wait pour être tranquille...

  12. #12
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 14
    Par défaut
    Papajoker : merci de l'information, je ne savais pas. En fait, la présence de ces caractères est liée au fait que parmi les tests que j'ai fait, je me suis interrogé sur l'encodage du fichier et les fins de lignes, et que j'ai transformé (avec Scite) l'encodage "code page properties" en "UTF-8 with BOM" (et que j'ai omis de revenir en arrière).

    Jipété : j'ai fait les tests suivants :

    • introduction du code
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      ret=$?
      if [ "$ret" != "0" ]; then
      	zenity --info --title="Erreur" --text="$debut / $duree / $nom"
      fi
      affiche effectivement les erreurs, c'est à dire la variable tronquée,
    • le même code, précédé soit de wait, soit de sync, soit des 2, le message d'erreur n'apparaît plus, mais toutes les lignes ne sont pas correctement traitées.

  13. #13
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 118
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 118
    Par défaut
    Félicitations !

    Bon sang, je n'étais pas loin avec ce bout de page de man :
    -stdin
    Enable interaction on standard input. On by default unless standard input is used as an input. To explicitly disable interaction you
    need to specify "-nostdin".

    Disabling interaction on standard input is useful, for example, if ffmpeg is in the background process group. Roughly the same result
    can be achieved with "ffmpeg ... < /dev/null" but it requires a shell.
    mais l'explication n'était pas claire, et je n'avais pas le temps de faire des tests.

    Bien joué !

    @OmegaZ : tu en profiteras pour corriger cette abomination :
    Le script va se terminer, relancez le
    -->
    Le script va se terminer, relancez-le

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Lecture d'un fichier texte dans un projet TOMCAT
    Par brice_nice dans le forum Tomcat et TomEE
    Réponses: 2
    Dernier message: 03/07/2005, 15h04
  2. lecture d'un fichier texte
    Par benahpets dans le forum MFC
    Réponses: 5
    Dernier message: 22/06/2005, 11h50
  3. [C#] Lecture d'un fichier texte (farfelu)
    Par choas dans le forum Windows Forms
    Réponses: 3
    Dernier message: 11/04/2005, 14h33
  4. Lecture d'un fichier Texte
    Par jcharles dans le forum Bases de données
    Réponses: 8
    Dernier message: 27/10/2004, 14h58
  5. Stockage de données & lecture d'un fichier texte
    Par petitours dans le forum C++Builder
    Réponses: 6
    Dernier message: 13/03/2004, 14h05

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