[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. 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
    
    $

    ;-))
    1
    1. 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
      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
        ;-)
        0
    2. 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
      0
      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...
        0
        1. 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
          
          0
          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 ??
            0
            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
              0
            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
              0
            3. Contributeur
              Affiche le résultat de la commande :

              cat -A test
              0
            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$  
               
              0
            5. Ah c'est bon sa marche, il faut en fait que je remplace tout les ^M par \r à priori
              0