TD numéro 2 du cours système du MMFAI 1998-99 dirigé par Serge Vaudenay.

Traitement de fichiers

  1. De nombreuses applications demandent d'extraire un sous-fichier d'un même fichier. Par exemple, si l'on rédige un document composé de textes en anglais et de commandes, et que l'on souhaite passer le texte au travers du filtre spell, il est souhaitable de ne pas faire passer les commandes avec, sous peine d'obtenir une avalanche de mots inconnus de spell. On cherche donc à faire (en Perl) un filtre list qui puisse extraire certaines lignes du fichier. On spécifie les lignes à extraire en activant le filtre par un mot-clef avant, et en le désactivant par un autre mot-clef. On décide que ces mots-clef soient respectivement "filter list on" et "filter list off". Par exemple, si le fichier toto contient
      #! /bin/sh
      
      if [ $# != 1 ]
      then
        echo "un seul argument svp"
        exit 1
      fi
      
      cat >> $1 <<END # filter list on
             Perl is a language optimized for scanning arbitrary text
             files, extracting information from those text files, and
             printing reports based on that information.  It's also a
             good language for many system management tasks.  The
             language is intended to be practical (easy to use,
             efficient, complete) rather than beautiful (tiny, elegant,
             minimal).
      END
      # filter list off
      
      exit 0
      
    la commande list toto donne en sortie standard
             Perl is a language optimized for scanning arbitrary text
             files, extracting information from those text files, and
             printing reports based on that information.  It's also a
             good language for many system management tasks.  The
             language is intended to be practical (easy to use,
             efficient, complete) rather than beautiful (tiny, elegant,
             minimal).
      END
      
    et l'on peut faire list toto | spell.
    [
    corrigé]

  2. Faire une commande accent qui convertie les différents formats de caractères accentués. Par exemple,
      accent tex <file1> iso <file2>
    recopie dans <file2> le fichier <file1> en remplaçant "\'e" par "é", ... Voici une liste des substitutions à faire.
    texisoepellehtml
    \'eée'&eacute;
    \`eèe`&egrave;
    \^eêe^&ecirc;
    \`aàa`&agrave;
    \^aâa^&acirc;
    \^oôo^&ocirc;
    \`uùu`&ugrave;
    \"uüu"&uuml;
    \^{\i}îi^&icirc;
    \"{\i}ïi"&iuml;
    \c{c}çc,&ccedil;
    {\oe}oeoeoe
    {\ae}æae&aelig;

    [
    corrigé]

  3. On généralise l'exercice 1. On souhaite faire une commande split telle que
      split toto
      
    effectue les instructions suivantes.
    1. Elle prend le fichier toto, et le parcours ligne-par-ligne jusqu'à trouver le mot-clef "split control parameters".
    2. Cette ligne et la suite du chichier sont interprétées suivant le motif
        split control parameters<delimiter><commands><delimiter><end of line>
      <delimiter> est un caractère quelconque utilisé comme délimiteur, <commands> est une chaîne de caractères (éventuellement avec des sauts à la ligne) ne contenant pas le délimiteur, et end of line> est la fin de la ligne qui contient le délimiteur.
    3. La chaîne de caractères <commands> est interprétée comme une suite de chaînes de caractères (séparés par des espaces ou des passages à la ligne). Chaque chaîne représente une commande.
    4. Les commandes sont éxécutées (voir la liste des commandes plus bas). A la fin, le programme doit obtenir une table de mots-clef et de fichiers. A chaque mot-clef doit correspondre un fichier.
    5. La commande continue de lire la suite du fichier ligne-par-ligne en les recopiant dans une liste de fichiers. A chaque fois qu'une ligne contenant au moins un mot-clef est rencontré, cette ligne n'est pas recopiée, mais les lignes suivantes sont recopiées à nouveau dans la liste de fichiers correspondant aux mots-clef de la ligne.
    Voici la liste des commandes.
    • ignore <str> Dans la suite de la liste <commands>, ignore les chaînes égales à <str>.
    • thisfile <character> Dans la suite de la liste <commands>, remplace dans les noms de fichier les occurrences du caractère <character> par le nom du fichier traité.
    • keyword <keyword> <file> Crée un mot-clef <keyword> associé au nom de fichier <file> (éventuellement substitué).
    • default <keyword1> [<keyword2> [...]] Recopie les premières lignes du fichier, ainsi que les suivantes (jusu'aux prochains mots-clef) dans la liste des fichiers correspondant aux mots-clefs suivant. (Cette commande doit être la dernière.)
    Par exemple, si exo1 contient
      #! /bin/perl
      # split control parameters"ignore #
      #   thisfile @
      #   keyword split_ignore /dev/null
      #   keyword split_exo_fr @_fr.html
      #   keyword split_cor @_cor
      #   keyword split_exo_en @_en.html
      #   default split_cor
      # "
      
      while ($line=<>) {
        print $line;
      }
      exit 0;
      # split_exo_fr split_exo_en
      <html><head></head><body>
      # split_exo_fr
      Faire un filtre analogue à <code>cat</code> qui recopie
      l'entrée standard dans la sortie standard.
      </body></html>
      # split_exo_en
      Write a Perl filter which as <code>cat</code> copies the standard
      input into the standard output.
      # split_exo_fr split_exo_en
      </body></html>
      
    la commande va créer trois fichiers: exo1_fr.html, exo1_en.html et exo1_cor. A la fin, exo1_fr.html contientdra
      <html><head></head><body>
      Faire un filtre analogue à <code>cat</code> qui recopie
      l'entrée standard dans la sortie standard.
      </body></html>
      
    exo1_en.html contientdra
      <html><head></head><body>
      Write a Perl filter which as <code>cat</code> copies the standard
      input into the standard output.
      </body></html>
      
    et exo1_cor contientdra
      #! /bin/perl
      
      while ($line=<>) {
        print $line;
      }
      exit 0;
      
    [corrigé] [solution de JB]