Forum Programmation.shell Générer des fichiers texte selon un modèle

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
0
27
déc.
2012

Bonjour,

j'utilise un script shell maison pour générer des fichiers textes (html) qui sont des signatures pour les emails.

J'ai un fichier de configuration :

modele_general=signature_general.html
modele_direction=signature_direction.html
logo=visuel.jpg

et un fichier « base de données » :

# fichier sortie      modèle            logo    email                         prénom nom         téléphone
rene.tartempion.html  $modele_general   $logo   rene.tartempion@example.com   René TARTEMPION    02.45.37.21.27
ghislaine.truc.html   $modele_general   $logo   ghislaine.truc@example.com    Ghislaine TRUC     02.45.37.21.71
philippe.lechef.html  $modele_direction $logo   philippe.lechef@example.com   Philippe LECHEF    02.45.37.21.21

Les modèles html contiennent un marquage pour chaque champ. Par exemple %%PRENOM%% est remplacé par le prénom de la personne.

Le gros intérêt est que chaque fois qu'il y a un changement dans un modèle de signature (fréquent dans le cas présent), il suffit de lancer le script et toutes les signatures sont générées avec les modifications.

Mon script génère un fichier pour chaque ligne de la base de données. Il fonctionne bien mais il est un poil compliqué (53 lignes en comptant tout).
Je me dis qu'il existe probablement une solution plus élégante pour produire ce genre de chose. Or je ne vois pas du tout ce que j'aurai pu utiliser à la place de mon script alambiqué.
Une idée ?

  • # awk/sed devraient suffire

    Posté par  . Évalué à 2. Dernière modification le 27 décembre 2012 à 14:02.

    je fais un truc similaire pour faire des mailings à partir de la ligne de commande, ca fait bien moins de 53 lignes

    boucle for sur la "base de données" : (1 Ligne)
    copier le modele en fichier de sortie (1 ligne)
    pour chaque ligne recuperer les champs avec awk (7 lignes)
    faire un sed s/MOTIF/remplacement/g dans le fichier html (7 lignes si tu fais 7 remplacements individuels)
    finir la boucle. (1 ligne)

    soit 17 lignes

    • [^] # Re: awk/sed devraient suffire

      Posté par  . Évalué à 2.

      Mon script fait 53 lignes car il gère les erreurs (champ manquant, erreur d'écriture d'un fichier, etc) et il y a des commentaires.
      Sinon je constate que je ne suis pas le seul à ne pas avoir trouvé la solution magique toute cuite :-)

  • # En python

    Posté par  (site web personnel) . Évalué à 1.

    En utilisant le moteur de template fourni par le module string :

    # parse config file
    kv = dict()  # holds the key/value
    with file('def.cfg') as f:
      for line in f:
        k, v = line.split('=',1)
        kv[k.strip()] = v.strip()
    
    # load the template
    from string import Template
    tpl = Template(file('tpl.txt').read())
    
    # perform substitution
    print tpl.substitute(**kv)
    
    
  • # Quelques exemples

    Posté par  (site web personnel) . Évalué à 2. Dernière modification le 08 janvier 2013 à 21:03.

    Voici une liste de techniques. Ma préférence personelle irait à la solution M4+AWK ou SED+AWK.

    Pour ton fichier base de données, je te conseille d'utilsier un séparateur (comme `|') plutôt que des blancs, le séparateur est beaucoup plus facile à manipuler (AWK, sort, shell IFS).

    Here-docs

    Interpolation des variables dans les here-documents du shell.

    Exemple:

    print_usage()
    {
      cat <<EOF
    ${PROGNAME} [-h]
     Does nothing special
    EOF
    }
    
    

    Tu peux l'interfacer avec une boucle for et jouer sur le input field splitting IFS pour faire ton mailing facilement.

    datasource()
    {
    cat <<EOF
    Pierre|21
    Paul|22
    Jacques|45
    EOF
    }
    
    prepare_text_loop()
    {
       local saved_ifs
       local name
       local age
    
       saved_ifs="$IFS"
       IFS='|'
       while read name age; do
         prepare_text "$name" "$age"
       done
       IFS="$saved_ifs"
    }
    
    prepare_text()
    {
    cat <<EOF
    $1 a $2 ans
    EOF
    }
    
    datasource | prepare_text_loop
    
    

    SED & AWK

    Ici tu as un fichier externe qui contient des champs génériques comme %%NOM%% et %%AGE%%. Tu utilises AWK pour lire ta base de données et préparer une commande SED qui remplacera les variables en question. Tu peux faire le pipe vers SED directement depuis AWK.

    M4 & AWK

    Ici tu utilises le préprocesseur générique M4 au lieu de SED pour produire le texte final. À part cela, la technique ressemble à la précédente.

    Écrire un programme spécialisé

    Tu peux bien-sûr écrire un programme spécialisé dans le langage de ton choix. Cela sort un peu de ta question de départ, plutôt dans le trip «vite fait, bien fait.» Si tu es déjà à l'aise avec SED et AWK, c'est un choix sûr. Si tu ne sais pas encore programmer en M4 cela ressemble beaucoup à TeX (on écrit un programme qui écrit sa propre suite).

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.