Forum Programmation.shell Traitement par lot et sed

Posté par  (site web personnel) .
Étiquettes : aucune
-1
18
mar.
2012

Bonjour, je dois automatiser la génération de fichier sql par rapport à un formulaire remplie par une personne pour ensuite l'importer dans une base.

L'idée est d'avoir un fichier template qui ressemble à ça :

USE thecom_--COMMUNAUTE--;
UPDATE gt_agora_info SET adresse_web="http://xxxxxxx/--COMMUNAUTE--/index.php", timezone="1.00", langue="francais";
INSERT INTO gt_espace SET id_espace="1", nom="--COMMUNAUTE--", description="";

INSERT 
    INTO 
        gt_utilisateur 
    SET
        nom="--NOM--",
        prenom="--PRENOM--",
        identifiant="--USERNAME--",
        pass="--USERPASSE--",
        mail="--EMAIL--",
        date_creation="--DATE--",
        espace_connexion="1";

INSERT INTO gt_agenda SET id_utilisateur="1", type="utilisateur";
INSERT INTO gt_jointure_messenger_utilisateur SET id_utilisateur_messenger="1", tous_utilisateurs="1";
INSERT INTO gt_jointure_espace_utilisateur SET id_espace="1", id_utilisateur="1", droit="1";

Ensuite j'ai mon petit script qui me parcours le fichier et remplace le valeur entre --XXX-- par celle récupéré par le formulaire et comme je suis flémar je suis passé par une fonction :

function replaceValue() {
    sed -i 's/--'$1'--/'$2'/g' $3
}

J'appelle ma fonction comme ça :

replaceValue "DATE" "$DATE" $SPOOLDIR/after-import-$COMMUNAUTE.sql

Sauf que je bloque pour la valeur de --DATE-- j'envoie cette valeur :

DATE=`date "+%Y-%m-%d %H:%M:%S"

Et sed me répond :

sed: -e expression n°1, caractère 21: commande `s' inachevée

J'ai bien compris que c'était l'espace qui posait problème mais sans trouver de solution. Est-ce que vous avez une idée ?

  • # Utilise des doubles-quotes.

    Posté par  . Évalué à 2.

    function replaceValue() {
        sed -i "s/--$1--/$2/g" $3
    }
    
    

    sed n'aime pas trop qu'on lui saucissonne les arguments.
    Mieux vaut utiliser les double-quotes qui interprêtent les variables.

    Par contre, une remarque plus générale, utiliser des données provenant d'un formulaire dans un shell sans en inspecter les valeurs pour générer une requête sql, c'est un poil risqué non ?

  • # Quelques suggestions

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

    La solution de Frédéric est très bien. Je la complète par quelques remarques:

    1. Il faut valider les données. (Frédéric l'a dit, mais on ne le répète jamais assez!)

    2. Cas particulier de 1., ta fonction de remplacement ne marche plus si ton entrée contient un caractère /.

    3. SED permet d'utiliser un autre caractère que / pour délimiter ses opérandes, si ton entrée peut contenir tout type de caractères imprimables, le mieux est d'utilsier un caractère… non-imprimable! Par exemple ^A (ASCII 1, obtenu par C-q C-a dans Emacs).

    4. Je suppose que tu fais un remplacement pour chaque variable. SED peut réaliser plusieurs opérations (avec l'option -e) ce qui te permettrait d'économiser des appels, au prix de quelques acrobaties avec les variables du shell. Une autre méthode permettant de ne faire qu'un seul appel à SED consiste à générer un script SED (paramètre -f de SED), par exemple à partir d'un HERE-DOC. C'est très pratique parceque les variables sont remplacées dans les HERE-DOC

    form_date=`date "+%Y-%m-%d %H:%M:%S"`
    form_nom='A. Nonyme'
    cat > replace.sed <<EOF
    s^A--DATE--^A${form_date}^Ag
    s^A--NAME--^A${form_nom}^Ag
    EOF
    sed -i '' -f replace.sed $SPOOLDIR/after-import-$COMMUNAUTE.sql
    
    

    Les HERE-DOCs sont une fonction très pratique (car on peut les piper) du shell, souvent sous-estimée.

    1. Quitte à faire du HERE-DOC, on peut aussi envisager de produire directement le fichier $SPOOLDIR/after-import-$COMMUNAUTE.sql avec un HERE-DOC, comme dans
    form_date=`date "+%Y-%m-%d %H:%M:%S"`
    form_nom='A. Nonyme'
    cat > $SPOOLDIR/after-import-$COMMUNAUTE.sql <<EOF
    
        SET
            nom="${form_nom}",
    
            date_creation="${form_date}",
    
    EOF
    
    
    1. La convention dans les scripts shell est plutôt d'utiliser la majuscules pour les variables d'environnement et les minuscules pour les variables du script. Ça évite notamment de modifier l'environnement par erreur.

    2. La mise-en page de mon commentaire avec Mark-Down est pas super.

    3. Il faut valider les données.

    XKCD: Exploits of a MOM

    • [^] # Re: Quelques suggestions

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

      Merci pour ces précisions et même réponse qu'à Frédéric, les données sont validés avant mais pas par le shell :)

      Je test tout ça, encore merci.

      Born to Kill EndUser !

      • [^] # Re: Quelques suggestions

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

        Alors je dirais pourquoi diable inserer les données dans la DB via du shell dans ce cas,
        c'est tout de même une drôle d'idée …

        • [^] # Re: Quelques suggestions

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

          Le formulaire est servi par du php, la personne rempli le bazar et tout un système de validation se met en place qui prend plus ou moins de temps. Ensuite un traitement se lance tout les x temps, l'intérêt est que l'utilisateur n'a pas attendre devant son écran que tout ce valide, que l'install se fasse. Il a juste à attendre le mail de confirmation. Ca permet aussi de gérer une file d'attente pour la création.

          Born to Kill EndUser !

  • # Utiliser m4

    Posté par  . Évalué à 3.

    Depuis quelques temps, j'utilise m4 pour ce qui est template, et c'est plutôt pas mal : c'est vraiment fait pour ça, et ça s'invoque facilement

    m4 -DNOM=Dupont -DPRENOM=Jean < in > out
    
    

    Et tu peux aller beaucoup plus loin en définissant des macros, si t'as envie.

Suivre le flux des commentaires

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