[Shell] Commande programmation

Résolu
Bonjour,

Je me lance dans la programmation en shell et j'ai quelques petits problèmes au niveau de l'écriture et de comment faire ce que je veux.
Mon but est de convertir un fichier html en fichier ics.

Tout d'abord j'ai besoin d'insérer des retour chariots, je les fais avec la commande sed en utilsant : [CTRL] +V puis [CTRL] + M.
sed -i 's|ABC-|^M|g' monfichier

Celà fonctionne correctement lorsque je le tape dans le terminal mais lorsque je met ^M dans un fichier .sh qui me lance une suite de commande la commande ^M ne fonctionne pas comme retour chariot, ça m'insère correctement le ^M mais il n'est pas pris comme retour chariot ensuite dans le fichier.
Comment puis-je faire ??

Ensuite, j'ai une suite d'éléments dans mon fichier: (une centaine de lignes similaires)
07/09/2010;Accueil;13:00;1h;4-r0-2

qui correspondent à : la date;la matière;l'heure;la durée;la salle
J'aimerais avoir ça en sortie; changer l'ordre
Accueil;4-r0-2;07/09/2010;13:00;1h


J'ai essayé avec ce genre de commande mais ça fonctionne pas comme je veux
sed -i 's|\(.*;.*;\)\([0-9]\{2\}\)\([0-9]\{2\}\)\([0-9]\{1\}\)|\1\2\3\|g' monfichier


Et au final, il faut que j'arrive à quelque chose dans ce genre:
BEGIN:VEVENT
SUMMARY:Accueil
LOCATION:4-r0-2
DTSTART:20100907T130000Z
DTEND:20100907T140000Z
END:VEVENT


Je pense savoir comment rajoutter les "SUMMARY", "LOCATION", etc
mais j'ai un petit soucis en ce qui concerne l'heure de fin de l'évènement qui doit être trouvé à partir de l'heure de début ainsi que de la durée.

Merci pour votre aide précieuse.
--
Romain

6 réponses

Résumé de la discussion

Le fil porte sur la conversion d'un fichier HTML en ICS via shell, avec des difficultés pour insérer des retours chariot et réorganiser les champs. Des propositions portent sur sed pour remplacer des séparateurs par des retours à la ligne, l'utilisation de ^M ou de \n, et l'assemblage des données en BEGIN:VEVENT et END:VEVENT. En parallèle, certains proposent d'extraire et reformater l'entrée hors du code (exemple avec w3m pour obtenir du texte structuré), tandis que d'autres insistent sur les limites des fins de ligne Windows vs Linux. Certains échanges illustrent des commandes sed complètes pour réordonnancer les champs, et des questions sur l'insertion en place dans le fichier, sans aboutir à une solution universelle.

Bobot (l’IA à votre service)
  1. Nouvelle bonne nouvelle !
    Le fichier ics a un paramètre 'DURATION' qui est la durée de l'évènement donc je n'ai plus besoin de faire le temps de fin avec une somme ce qui va faciliter grandement les choses.

    J'arrive à faire cette sortie maintenant:
    BEGIN:VEVENT
    SUMMARY:Accueil
    LOCATION:4-r0-2
    DTSTART:07/09/201013:00
    DURATION:1h
    END:VEVENT


    Ma nouvelle question: Comment appliquer un sed sur une ligne en particulier, je m'explique j'ai besoin de changer le 'h' de la durée en H mais pas les h des autres lignes. Comment faire ?
    De meme pour changer le format de la ligne DTSTART: j'ai la commande qui fonctionne si je met juste 07/09/201013:00 en entrée mais comment l'appliquer à cet endroit en particulier ??
    1. Contributeur
      $ cat fich
      BEGIN:VEVENT
      SUMMARY:Accueil
      LOCATION:4-r0-2
      DTSTART:07/09/201013:00
      DURATION:1h
      END:VEVENT
      
      $ sed '/^DURATION/ s/h/H/' fich
      BEGIN:VEVENT
      SUMMARY:Accueil
      LOCATION:4-r0-2
      DTSTART:07/09/201013:00
      DURATION:1H
      END:VEVENT
    2. Ah ! Sa marche pas ... :-(

      J'ai un fichier texte avec mon texte qui s'appelle test
      BEGIN:VEVENT  
      SUMMARY:Accueilh  
      LOCATION:4-r0-2  
      DTSTART:07/09/201013:00  
      DURATION:1h  
      END:VEVENT  
      


      Je fais ta commande: sed -i '/^DURATION/ s/h/H/' test
      Mais j'ai rien qui change dans mon fichier de sortie. J'ai toujours le h minuscule, c'est bizarre
    3. Contributeur
      Affiche le résultat de la commande :

      cat -A test
    4. romain@romain-linux:~/Bureau$ cat -A test  
      BEGIN:VEVENT^MSUMMARY:Accueilh^MLOCATION:4-r0-2^MDTSTART:07/09/201013:00^MDURATION:1h^MEND:VEVENT^Mromain@romain-linux:~/Bureau$  
       
    5. Ah c'est bon sa marche, il faut en fait que je remplace tout les ^M par \r à priori
  2. Contributeur
    Juste un truc avant d'aller plus loin, quand tu récupères ton fichier html, plus tôt que de traiter le code source, ne serait-il pas plus simple de traiter la sortie déjà formatée ?

    Un exemple avec "w3m" :

    $ cat plop.html 
    <BODY class="margin"> 
    <table> 
    <tr class="subHeader1"> 
            <td colspan=4>Activité</td> 
                    <td  colspan=1>Salles</td></tr> 
    <tr class="subHeader1"><td><a href="info.jsp?order=slot&light=true">Date</a></td><td><a href="info.jsp?order=activityName&light=true">Nom</a></td><td><a href="info.jsp?order=hour&light=true">Heure</a></td><td><a href="info.jsp?order=duration&light=true">Durée</a></td><td><a href="info.jsp?order=cat3Name&light=true">Nom</a></td></tr> 
    <tr><td><SPAN CLASS="value">07/09/2010</span></td><td><a href="javascript:ev(1008)">Accueil</a></td><td>13:00</td><td>1h</td><td>4-r0-2 </td></tr><tr><td><SPAN CLASS="value">08/09/2010</span></td><td><a href="javascript:ev(1518)">Resis Mat</a></td><td>14:00</td><td>1h20min</td><td>3-r0-7 </td></tr><tr><td><SPAN CLASS="value">08/09/2010</span></td><td><a href="javascript:ev(7069)">Caract Mat</a></td><td>15:30</td><td>1h20min</td><td>3-r0-7 </td></tr><tr><td><SPAN CLASS="value">09/09/2010</span></td><td><a href="javascript:ev(1417)">Resis Mat</a></td><td>09:30</td><td>1h20min</td><td>4-r0-4 </td></tr><tr><td><SPAN CLASS="value">09/09/2010</span></td><td><a href="javascript:ev(2109)">Méth. Opti</a></td><td>11:00</td><td>1h20min</td><td>4-r0-4 </td></tr><tr><td><SPAN CLASS="value">09/09/2010</span></td><td><a href="javascript:ev(2710)">Stages et Semestre à l'Etranger</a></td><td>14:00</td><td>1h</td><td>0-r0-2 : Amphi 300 ... 
    
    $ w3m -dump -T text/html plop.html 
    Activité                                                 Salles 
    Date       Nom                             Heure Durée   Nom 
    07/09/2010 Accueil                         13:00 1h      4-r0-2 
    08/09/2010 Resis Mat                       14:00 1h20min 3-r0-7 
    08/09/2010 Caract Mat                      15:30 1h20min 3-r0-7 
    09/09/2010 Resis Mat                       09:30 1h20min 4-r0-4 
    09/09/2010 Méth. Opti                      11:00 1h20min 4-r0-4 
    09/09/2010 Stages et Semestre à l'Etranger 14:00 1h      0-r0-2 : Amphi 300 ... 
    
    

    ;-))

    Zen my nuggets ;-)
    1. Ah je savais même pas que c'était possible.
      Non mais je vais continuer avec ma méthode de bourrin qui fonctionne pour le passer en fichier texte
      ;-)
  3. Bonne nouvelle, j'ai trouvé comment faire mon retour chariot grâce à mon script : il suffisait d'utiliser le caractère \r qui correspond au retour chariot.

    le code :

    sed -i 's|ABC-|\r|g' test
    
    1. Sinon ta commande un peu modifié fonctionne cependant elle fonctionne pour une seule ligne.
      La commande:
      sed -i 's|\([^;]*\);\([^;]*\);\([^;]*\);\([^;]*\);\(.*\);|\2;\5;\1;\3;\4|g' test
      


      Entrée:
      08/09/2010;Resis Mat;14:00;1h20min;3-r0-7;

      Sortie:
      Resis Mat;3-r0-7;08/09/2010;14:00;1h20min


      C'est bon !

      Par contre pour plusieurs lignes:
      Entrée:
      07/09/2010;Accueil;13:00;1h;4-r0-2;
      08/09/2010;Resis Mat;14:00;1h20min;3-r0-7;

      Sortie:
      Accueil;4-r0-2;
      08/09/2010;Resis Mat;14:00;1h20min;3-r0-7;07/09/2010;13:00;1h

      Là sa fonctionne plus...
      1. Salut,

        Voici ce que j'obtiens avec un précédent script que j'ai récupéré sur google code et modifié. Ce script va chercher mon emploi du temps sur internet et me génère un fichier html qui ressemble à ça:

        <BODY class="margin">
        <table>
        <tr class="subHeader1">
        	<td colspan=4>Activité</td>
        		<td  colspan=1>Salles</td></tr>
        <tr class="subHeader1"><td><a href="info.jsp?order=slot&light=true">Date</a></td><td><a href="info.jsp?order=activityName&light=true">Nom</a></td><td><a href="info.jsp?order=hour&light=true">Heure</a></td><td><a href="info.jsp?order=duration&light=true">Durée</a></td><td><a href="info.jsp?order=cat3Name&light=true">Nom</a></td></tr>
        <tr><td><SPAN CLASS="value">07/09/2010</span></td><td><a href="javascript:ev(1008)">Accueil</a></td><td>13:00</td><td>1h</td><td>4-r0-2 </td></tr><tr><td><SPAN CLASS="value">08/09/2010</span></td><td><a href="javascript:ev(1518)">Resis Mat</a></td><td>14:00</td><td>1h20min</td><td>3-r0-7 </td></tr><tr><td><SPAN CLASS="value">08/09/2010</span></td><td><a href="javascript:ev(7069)">Caract Mat</a></td><td>15:30</td><td>1h20min</td><td>3-r0-7 </td></tr><tr><td><SPAN CLASS="value">09/09/2010</span></td><td><a href="javascript:ev(1417)">Resis Mat</a></td><td>09:30</td><td>1h20min</td><td>4-r0-4 </td></tr><tr><td><SPAN CLASS="value">09/09/2010</span></td><td><a href="javascript:ev(2109)">Méth. Opti</a></td><td>11:00</td><td>1h20min</td><td>4-r0-4 </td></tr><tr><td><SPAN CLASS="value">09/09/2010</span></td><td><a href="javascript:ev(2710)">Stages et Semestre à l'Etranger</a></td><td>14:00</td><td>1h</td><td>0-r0-2 : Amphi 300 ...


        Donc là je supprime tout ce qui concerne les balises html pour arriver à un fichier de ce genre:

        07/09/2010;Accueil;13:00;1h;4-r0-2 
        08/09/2010;Resis Mat;14:00;1h20min;3-r0-7 
        08/09/2010;Caract Mat;15:30;1h20min;3-r0-7 
        09/09/2010;Resis Mat;09:30;1h20min;4-r0-4 
        09/09/2010;Méth. Opti;11:00;1h20min;4-r0-4 
        09/09/2010;Stages et Semestre à l'Etranger;14:00;1h;0-r0-2 : Amphi 300 


        Grace à ce code que j'ai mis dans un fichier script en .sh

        sed -i '1,37 d' test
        sed -i '2,3 d' test
        
        sed -i 's|<tr><td><SPAN CLASS="value">|ABC-|g' test
        sed -i 's|</span></td><td><a href="javascript:ev(.....)">|;|g' test
        sed -i 's|</span></td><td><a href="javascript:ev(....)">|;|g' test
        sed -i 's|</span></td><td><a href="javascript:ev(...)">|;|g' test
        sed -i 's|</span></td><td><a href="javascript:ev(..)">|;|g' test
        sed -i 's|</a></td><td>|;|g' test
        sed -i 's|</td><td>|;|g' test
        sed -i 's|</td></tr>||g' test


        Jusque là tout va bien, à part que je dois faire manuellement les retours à la ligne pour chaque évènement car comme j'ai dit dans mon précédent message le ^M dans mon fichier script fonctionne pas et en le tapant avec CTRL +V et CTRL +M fonctionne.

        et maintenant je sais plus trop comment faire pour la "finition"
        Le fichier final devra ressembler à ça : (fichier .ics pour importer dans google agenda)
        BEGIN:VCALENDAR
        
        BEGIN:VEVENT
        DTSTART:20100907T130000Z
        DTEND:20100907T140000Z
        SUMMARY:Accueil
        LOCATION:4-r0-2 
        END:VEVENT
        
        BEGIN:VEVENT
        DTSTART:20100908T140000Z
        DTEND:20100908T152000Z
        SUMMARY:Resis Mat
        LOCATION:3-r0-7 
        END:VEVENT
        
        BEGIN:VEVENT
        DTSTART:20100908T153000Z
        DTEND:20100908T165000Z
        SUMMARY:Caract Mat
        LOCATION:3-r0-7 
        END:VEVENT
        
        BEGIN:VEVENT
        DTSTART:20100909T093000Z
        DTEND:20100909T105000Z
        SUMMARY:Resis Mat
        LOCATION:4-r0-4 
        END:VEVENT
        
        ...
        
        END:VCALENDAR


        Donc pour ce qui est de rajoutter la syntaxe du format ics sa devrait aller par contre le problème c'est pour cette ligne: DTEND:20100907T140000Z
        qui est du type: yyyymmjjThhmmssZ
        Sauf que moi j'ai l'heure de début et la durée et que donc il faut qu'il calcule l'heure de fin mais je ne sous-estime pas linux et je suis sur qu'il en est capable !!

        J'essaye ce que tu m'as dit pour l'ordre sa me permettra d'avancer un peu plus
        1. Contributeur
          Salut,

          Peux-tu poster un exemple concret AVANT => APRÈS de ce que tu veux exactement ? S'il te plaît, merci.

          Sinon déjà, concernant la commande "sed", essaie ça :

          $ echo $A
          07/09/2010;Accueil;13:00;1h;4-r0-2
          
          $ echo $A | sed 's/\([^;]*\);\([^;]*\);\([^;]*\);\([^;]*\);\(.*\)/\2;\5;\1;\3;\4/'
          Accueil;4-r0-2;07/09/2010;13:00;1h
          
          $

          ;-))