IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Administration système Discussion :

Script AWK et traitement de fichier


Sujet :

Administration système

  1. #1
    Membre du Club
    Inscrit en
    Février 2005
    Messages
    144
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 144
    Points : 62
    Points
    62
    Par défaut Script AWK et traitement de fichier
    Bonjour,

    j'ai un fichier test.sql formaté de la sorte :

    email
    ----------------------------------------------------
    0033@mail.fr
    007@mail.fr
    mc@mail.fr

    je souhaiterais formaté le fichier comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    INSERT INTO module (uid, mail) VALUES (1,'0033@mail.fr');
    INSERT INTO module (uid, mail) VALUES (1,'007@mail.fr');
    INSERT INTO module (uid, mail) VALUES (1,'mc@mail.fr');
    j'utilise AWK en ligne de commande comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F \| -v Q=\' '{ prov=($1~/^ *$/)?"":uid;printf ("INSERT INTO module (uid, mail) VALUES (1,%s);\n",Q $1 Q) }' test.sql > test1.sql
    mais j'ai pas tout a fait ce que je souhaite en sortie dans test1.sql :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    INSERT INTO module (uid, mail) VALUES (1,'                       email                        ');
    INSERT INTO module (uid, mail) VALUES (1,'----------------------------------------------------');
    INSERT INTO module (uid, mail) VALUES (1,' 0033@mail.fr');
    INSERT INTO module (uid, mail) VALUES (1,' 007@mail.fr');
    INSERT INTO module (uid, mail) VALUES (1,' mc@mail.fr');
    il me prend le titre de la colonne email puis la séparation hors je voudrais les supprimer. De plus il me laisse un espace entre le

    1,' 0033' au lieu de 1,'0033'
    1,' 007' au lieu de 1,'007'
    1,' mc' au lieu de 1,'mc'

    Que dois je modifier dans ma ligne AWK?

    Merci

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2006
    Messages : 107
    Points : 124
    Points
    124
    Par défaut
    Salut,

    tu peux t'en tirer avec la commande suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    grep -v "email" test.sql | grep -v -- "-.*" | tr -d '[:blank:]' | awk -F \| -v Q=\' '{ prov=($1~/^ *$/)?"":uid;printf ("INSERT INTO module (uid, mail) VALUES (1,%s);\n",Q $1 Q) }' > test1.sql
    ça marche, même si c'est surement pas le plus efficace !

  3. #3
    Membre du Club
    Inscrit en
    Février 2005
    Messages
    144
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 144
    Points : 62
    Points
    62
    Par défaut
    Merci cela fonctionne. Tu peux juste m'expliquer cela surtout le -.* :
    Merci

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2006
    Messages : 107
    Points : 124
    Points
    124
    Par défaut
    Citation Envoyé par pcsystemd Voir le message
    Merci cela fonctionne. Tu peux juste m'expliquer cela surtout le -.* :
    Merci
    le -v de grep permet d'inverser le résultat de la commande : grep affiche uniquement les lignes ne correspondant pas au motif fourni.
    le motif "-.*" est une expression régulière : '.' désigne n'importe quel caractère, '*'indique que le caractère précédent peut être répété plusieurs fois.
    '-.*' désigne donc une ligne commençant par '-' et suivi de n'importe quel caractère répété plusieurs fois.
    Du coup, je m'aperçoit que le motif '-+' ( - suivi de +) est bien mieux car il désigne une ligne commençant par '-' et répété une ou plusieurs fois.
    le -- permet d'indiquer à grep que la liste des options est terminée. En effet, le motif de recherche commence par un tiret et grep croit donc que c'est une option qu'on lui passe.

  5. #5
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep "@" test |sed "s/^/INSERT INTO module (uid, mail) VALUES (1,'/;s/$/');/" > test.sql
    1. grep: on ne garde que les lignes avec des @

    2. sed: on remplace
    2.1. le début de chaque ligne par INSERT INTO module (uid, mail) VALUES (1,'
    2.2. la fin de chaque ligne par ');

  6. #6
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 584
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 584
    Points : 19 461
    Points
    19 461
    Par défaut
    ça me parait bien compliquer, tout ça...

    pcsystemd, es-tu obligé de te servir de awk ? parce que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    cat test.sql
    email
    ----------------------------------------------------
    0033@mail.fr
    007@mail.fr
    mc@mail.fr
    sed -n "/@/s/\(.*\)/INSERT INTO module (uid, mail) VALUES (1,'\1');/p" test.sql
    INSERT INTO module (uid, mail) VALUES (1,'0033@mail.fr');
    INSERT INTO module (uid, mail) VALUES (1,'007@mail.fr');
    INSERT INTO module (uid, mail) VALUES (1,'mc@mail.fr');
    sinon awk possède aussi la capacité à tester l'existence d'une chaîne dans un ligne.

  7. #7
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    flute, j'oublie toujours les -n /p de sed

    Edit :
    du coup, on peut simplifier...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n "/@/s/^/INSERT INTO module (uid, mail) VALUES (1,'/;/@/s/$/');/p" test > test.sql
    (pour éviter d'avoir une mémorisation à chaque ligne... je ne sais pas ce qui vaut le mieux en terme de perfs )

    Edit2 : pour information, après test, ta version est 2 fois plus rapide N_BaH... donc vaut mieux mémoriser que doubler le remplacement de sed ! Bon à savoir
    Et chose amusante, il vaut mieux utiliser un grep et un pipe qu'une reconnaissance directement dans sed !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $ time grep "@" mailing |sed "s/^/INSERT INTO module (uid, mail) VALUES (1,'/;s/$/');/" > result_1
     
    real    0m9.24s
    user    0m9.86s
    sys     0m0.23s
    $ time sed -n "/@/s/^/INSERT INTO module (uid, mail) VALUES (1,'/;/@/s/$/');/p"  mailing > result_2
     
    real    0m10.29s
    user    0m10.12s
    sys     0m0.16s
    $ time sed -n "/@/s/\(.*\)/INSERT INTO module (uid, mail) VALUES (1,'\1');/p" mailing > result_3
     
    real    0m5.01s
    user    0m4.88s
    sys     0m0.12s

  8. #8
    Membre du Club
    Inscrit en
    Février 2005
    Messages
    144
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 144
    Points : 62
    Points
    62
    Par défaut
    Merci a vous tous.

    Alek-C : Quand j'exècute ta ligne de commande le fichier généré est vide, cela ne fonctionne pas.

    N_BaH : Ta ligne fonctionne mais j'ai toujours l'espace entre le 1,'espace0033 :

    :~/Desktop$ sed -n "/@/s/\(.*\)/INSERT INTO module (uid, mail) VALUES (1,'\1');/p" test.sql
    INSERT INTO module (uid, mail) VALUES (1,' 033@mail.fr');
    Merci encore

  9. #9
    Membre chevronné

    Homme Profil pro
    Responsable projets techniques
    Inscrit en
    Février 2003
    Messages
    980
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Responsable projets techniques
    Secteur : Biens de consommation

    Informations forums :
    Inscription : Février 2003
    Messages : 980
    Points : 1 894
    Points
    1 894
    Par défaut
    Pour moi, je check, j'ai peut être mal copié/collé, mais de toute façon, la commande de N_BaH est plus efficace.

    Pour la commande de N_BaH, tu dois avoir un espace dans ton fichier comportant des emails, essaye avec ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -n "/@/s/^\s*\(.*\)\s*$/INSERT INTO module (uid, mail) VALUES (1,'\1');/p" test.sql
    Edit: j'ai recopié ma commande dans un shell et elle marche... par contre, fais gaffe: j'ai pas utilisé le même nom de fichier que toi au départ
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep "@" test.sql |sed "s/^/INSERT INTO module (uid, mail) VALUES (1,'/;s/$/');/"
    Mais comme je l'ai dit, celle de N_BaH est plus efficace !

  10. #10
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 584
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 584
    Points : 19 461
    Points
    19 461
    Par défaut
    Je n'ai pas cet espace, sans doute existe-t-il dans ton fichier ? auquel cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    sed -n "/@/s/ \(.*\)/INSERT INTO module (uid, mail) VALUES (1,'\1');/p" test.sql
    #            ^ espace

  11. #11
    Membre du Club
    Inscrit en
    Février 2005
    Messages
    144
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 144
    Points : 62
    Points
    62
    Par défaut
    Merci a tous c'est ok cela fonctionne correctement maintenant.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Script AWK pour modifier un fichier
    Par leanima dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 13/04/2012, 12h49
  2. AWK : traitement de fichier
    Par zeus2005 dans le forum Applications et environnements graphiques
    Réponses: 8
    Dernier message: 16/06/2007, 22h24
  3. Script awk ou ksh pour découper un fichier xml
    Par Griffith dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 15/05/2007, 22h58
  4. Traitement de fichier en shell script
    Par sam.fet dans le forum Linux
    Réponses: 3
    Dernier message: 03/05/2006, 14h30
  5. Script de traitement de fichier
    Par llaurentt dans le forum Linux
    Réponses: 14
    Dernier message: 11/01/2006, 12h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo