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 21/09/2012, à 12:37

benwa666

[RESOLU] cut/sed/grep/regexp/… sur un fichier texte un peu foireux.

Bonjour,

J'ai des time codes de sous titres complètement foireux, je dois les projeter en live ce soir dans le ciné où je bosse. 
Voilà les sous titres foireux :   

1    00:02:19:17    00:02:22:05      
Où sont les jeunes en colère 
pour dire aujourd'hui: 

2    00:02:22:09    00:02:24:21      
“Va te faire foutre, ceci n'est pas juste” 
et se lèvent pour protester? 

Il faut que ça ressemble à ça en fait :   


00:02:19,000 --> 00:02:22,000 
Où sont les jeunes en colère 
pour dire aujourd'hui: 


00:02:22,000 --> 00:02:24,000 
“Va te faire foutre, ceci n'est pas juste” 
et se lèvent pour protester? 

Donc, foutre le 1, 2, 3, 4, ... sur une ligne seule. 
Virer les espaces superflus et rajouter '-->' entre les time in et time out. 
Changer les derniers ':' par une virgule. 
Et le plus dur : changer les 2 derniers chiffres de chaque time code. Le truc c'est qu'ils sont en 25ème de seconde et qu'il faut les foutre en millièmes de secondes. Par exemple 00:00:00:10 devient 00:00:00,400. 

Faut pouvoir dire : si après la virgule c'est zéro, écris 000. Si c'est entre 1 et 24, multiplie par 40. 

Voilà. Trop facile tongue 

Si quelqu'un peut me faire avancer, même un petit peu je suis preneur.

Dernière modification par benwa666 (Le 21/09/2012, à 14:03)


** J’adorerais changer le monde, mais ils ne veulent pas me fournir le code source.

Hors ligne

#2 Le 21/09/2012, à 14:03

benwa666

Re : [RESOLU] cut/sed/grep/regexp/… sur un fichier texte un peu foireux.

Voilà la solution :

#!/bin/bash

#On commence par matter le fichier dans $1 existe
[ ! -f $1 ] && { echo "Usage : $(basename $0) <fichier>"; exit 127; }



#On explique a bash que le separateur est \n et on garde l'ancien par princpe
_oldIFS=$IFS
IFS=$'\n'


#On lit le fichier ligne par ligne
for line in $(cat $1)
        {
                #On regarde si c'est la ligne qui nous interresse (aka est ce que ma match la regexp moche
                echo "$line" | grep -qP  "^[0-9]+.[0-9]+:[0-9]+:[0-9]+:[0-9]+.[0-9]+:[0-9]+:[0-9]+:[0-9]+"
                if [ $? -eq 0 ];
                then
                        #Si oui, on traite de facon un peu porcasse, y'a clairement plus classe
                        _id=$(echo $line | grep -Po "^[0-9]+")
                        # On init un variable pour stocker la ligne magique
                        _ts=""
                        #On fait une liste qui contient les deux timecodes, cette boucle tourne donc 2 fois par ligne interessante
                         for ts in $(echo $line | grep -Po "[0-9]+:[0-9]+:[0-9]+:[0-9]+")
                                 {
                                         #on extrait le numero de frame en otant le leading 0
                                         _timecode=$(echo -n $ts | cut -f 4 -d ':' | sed -e 's/^0//')
                                         #on extrait le reste du timecode
                                         _base=$(echo -n $ts | cut -f 1,2,3 -d ':' )
                                         #on calcule la corespondance frame -> temps
                                         _newtimecode=$(( _timecode * 40 ))
                                         #on lui rajoute le padding a coup de  0
                                         _ftimecode=$(printf "%03d" $_newtimecode)
                                         #Si c'est celui du debut, on l'ecrit dans la varibale sinon, c'est que c'est le second donc on
                                         #Complete la variable
                                         [ -z $_ts ] && _ts=$_base,$_ftimecode || _ts="$_ts --> $_base,$_ftimecode"

                                 }

                        #on affiche un \n pour replacer les lignes vides, puis une ligne avec l'id, puis la ligne timecode
                        printf "\n$_id\n$_ts\n"

                else
                #Si non, on affiche direct
                #'ttention, bug ici, echo "$line" va reinterprété ligne et donc interpreter le contenu, ce n'est pas une copie
                #RAW, donc risque de peter un coup quand tu aura des *, ! , et des "" mélangés. mais pas sur, a tester ;p
                        echo "$line"
                fi

        }

#On remet l'IFS en place par principe
IFS=$_oldIFS


#on quitte propre ;p
exit 0

** J’adorerais changer le monde, mais ils ne veulent pas me fournir le code source.

Hors ligne

#3 Le 21/09/2012, à 22:22

pingouinux

Re : [RESOLU] cut/sed/grep/regexp/… sur un fichier texte un peu foireux.

Bonsoir,
Autre solution, en une ligne de awk, mais pas très lisible :

awk --posix '{if($0~/^[[:space:]]*[[:digit:]]+([[:space:]]+([[:digit:]]{2}:){3}[[:digit:]]{2}){2}[[:space:]]*$/){split($2,a2,":");split($3,a3,":");printf("%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n",$1,a2[1],a2[2],a2[3],40*a2[4],a3[1],a3[2],a3[3],40*a3[4])}else {print}}'  fichier.txt

Hors ligne