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

Shell et commandes POSIX Discussion :

Création d'un script AWK pour modifier un fichier


Sujet :

Shell et commandes POSIX

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2012
    Messages : 9
    Par défaut Création d'un script AWK pour modifier un fichier
    Bonjour,

    Mon but est de transformer un fichier via un script AWK

    Fichier initial: fic1.csv
    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
    Date: 27-Sep-2019
    Description 1
    Description 2
    Description 3
     
    Entete 1
     
     
    COLONNE1   COL2   XXX XXXXXXXXXXXX XXXXX
    123456789    FR12345  CEXXXXXX     DUPONT   HENRI   12-08-1950    12800    GU    120  EUR     CARTE    CREDIT   11
    123456789    FR12345  CEXXXXXX     DUPONT   HENRI   12-08-1950    12800    GA    150  EUR     CARTE    DEBIT   20    
    412566655    FR43333  CEXXXXXX     MARTIN   LUCIEN   20-02-2000    13200    GA    420  EUR     CARTE    DEBIT   1  
    842216654    FR8523  CEXXXXXX     LECOMTE    CATHERINE   21-08-1989    43520    GC    25000  EUR     CARTE    DEBIT   15
    9876543210    FR456788  CEXXXXXX     MARTIN   JACQUES   21-08-1902    94250    GA    3600  EUR     CARTE    DEBIT   58  
    9876543210    FR456788  CEXXXXXX     MARTIN   JACQUES   21-08-1902    94250    GC    25000  EUR     CARTE    DEBIT   120
    Fichier qui doit être généré: fic2.csv
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    1;412566655;FR43333;MARTIN;LUCIEN;20-02-2000;13200;EUR;CARTE;GA;420;DB;1;
    2;123456789;FR12345;DUPONT;HENRI;12-08-1950;12800;EUR;CARTE;GU;120;CR;GA;150;DB;31;
    1;842216654;FR8523;LECOMTE;CATHERINE;21-08-1989;43520;EUR;CARTE;GC;25000;DB;15;
    2;9876543210;FR456788;MARTIN;JACQUES;21-08-1902;94250;EUR;CARTE;GA;3600;DB;GC;25000;DB;178;
    J'ai réussi à le faire avec une suite de commandes awk, mais je ne parviens pas à écrire un seul script awk du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    BEGIN {
        # Things to be done before you start processing rows.
    }
    {
        # Things to be done for each row.
    }
    END {
        # Things to be done after processing the last row.
    }
    Suite de commandes awk pour parvenir au résultat souhaité
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat test.csv | awk 'f;/COLONNE1   COL2/{f=1}' | awk -F'\t' '$1!=""' | awk -F' ' '{$3=""}1' | awk '{$1=$1};1' FS=";" | awk '{$2=$2};1' OFS=";" | awk 'BEGIN{FS=OFS=";"} {if ($11=="CREDIT") {$11="CR"} else {$11="DB"}}1' | awk '{print $0";"}'  | awk -F';' '{occ[$1 ";" $2 ";" $3 ";" $4 ";" $5 ";" $6 ";" $9 ";" $10]++;sum[$1 ";" $2 ";" $3 ";" $4 ";" $5 ";" $6 ";" $9 ";" $10]+=$12;a[$1 ";" $2 ";" $3 ";" $4 ";" $5 ";" $6 ";" $9 ";" $10]=a[$1 ";" $2 ";" $3 ";" $4 ";" $5 ";" $6 ";" $9 ";" $10] ";" $7 ";" $8 ";" $11} END {for (k in a) {print occ[k] ";" k a[k] ";" sum[k] ";"}}'
    awk 'f;/COLONNE1 COL2/{f=1}' --> suppression de l'en-tête du fichier
    awk -F'\t' '$1!=""' --> suppression des lignes blanches à la fin du fichier
    awk -F' ' '{$3=""}1' --> suppression du 3ème champ
    awk '{$1=$1};1' FS=" " --> suppression des espaces inutiles entre les champs
    awk '{$2=$2};1' OFS=";" --> séparateur est un ';' au lieu d'un ' '
    awk 'BEGIN{FS=OFS=";"} {if ($11=="CREDIT") {$11="CR"} else {$11="DB"}}1' --> changementCREDIT en CR et DEBIT en DB
    awk '{print $0";"}' --> ajout d'un ';' à la fin de chaque ligne
    awk -F';' '{occ[$1 ";" $2 ";" $3 ";" $4 ";" $5 ";" $6 ";" $9 ";" $10]++;sum[$1 ";" $2 ";" $3 ";" $4 ";" $5 ";" $6 ";" $9 ";" $10]+=$12;a[$1 ";" $2 ";" $3 ";" $4 ";" $5 ";" $6 ";" $9 ";" $10]=a[$1 ";" $2 ";" $3 ";" $4 ";" $5 ";" $6 ";" $9 ";" $10] ";" $7 ";" $8 ";" $11} END {for (k in a) {print occ[k] ";" k a[k] ";" sum[k] ";"}}' --> regroupement en fonction des champs "$1 - $2 - $3 - $4 - $5 - $6 - $9 - $10"; ajout nombre d'occurrence en début de ligne; cumul du dernier champ

    Merci de votre aide

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2010
    Messages
    345
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 345
    Par défaut
    Bonjour,
    Si l'ordre n'est pas important, comme ça peut être?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -v b=";" 'f&&NF{$12=$12=="DEBIT"?"DB":"CR";a=$1b$2b$4b$5b$6b$7b$10b$11;++c[a];e[a]=e[a]$8b$9b$12b;g[a]=g[a]+$13;next};/COLONNE1   COL2/{f=1}END{for(i in c)print c[i]b i b e[i]g[i]b}' fic1.csv
    Cordialement.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2012
    Messages : 9
    Par défaut
    Bonjour,

    Merci beaucoup ctac_

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -v b=";" 'f&&NF{$12=$12=="DEBIT"?"DB":"CR";a=$1b$2b$4b$5b$6b$7b$10b$11;++c[a];e[a]=e[a]$8b$9b$12b;g[a]=g[a]+$13;next};/COLONNE1   COL2/{f=1}END{for(i in c)print c[i]b i b e[i]g[i]b}' fic1.csv
    Pourriez-vous m'expliquer ce qui suit
    f&&NF

    Le fichier d'origine a un peu été modifié et j'essaie d'adapter la commande

    Fichier initial: test_new.csv
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    123456789,FR12345,CEXXXXXX,DUPONT,HENRI,12-08-1950,12800,GU,120,EUR,CARTE,CREDIT,11
    123456789,FR12345,CEXXXXXX,DUPONT,HENRI,12-08-1950,12800,GA,150,EUR,CARTE,DEBIT,20    
    412566655,FR43333,CEXXXXXX,MARTIN,LUCIEN,20-02-2000,13200,GA,420,EUR,CARTE,DEBIT,1  
    842216654,FR8523,CEXXXXXX,LECOMTE,CATHERINE,21-08-1989,43520,GC,25000,EUR,CARTE,DEBIT,15
    9876543210,FR456788,CEXXXXXX,MARTIN,JACQUES,21-08-1902,94250,GA,3600,EUR,CARTE,DEBIT,58  
    9876543210,FR456788,CEXXXXXX,MARTIN,JACQUES,21-08-1902,94250,GC,25000,EUR,CARTE,DEBIT,120


    Fichier qui doit être généré: test_new_2.csv
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    1;412566655;FR43333;MARTIN;LUCIEN;20/02/2000;13200;EUR;CARTE;GA;420;DB;1;
    2;123456789;FR12345;DUPONT;HENRI;12-08/1950;12800;EUR;CARTE;GU;120;CR;GA;150;DB;31;
    1;842216654;FR8523;LECOMTE;CATHERINE;21/08/1989;43520;EUR;CARTE;GC;25000;DB;15;
    2;9876543210;FR456788;MARTIN;JACQUES;21/08/1902;94250;EUR;CARTE;GA;3600;DB;GC;25000;DB;178;

    j'ai modifié la commande que vous m'aviez gentiment communiquée par contre la 1ère ligne du fichier initial n'est pas prise en compte

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -v b=";" '{FS=","} f&&NF{$12=$12=="DEBIT"?"DB":"CR";a=$1b$2b$4b$5b$6b$7b$10b$11;++c[a];e[a]=e[a]$8b$9b$12b;g[a]=g[a]+$13;next};{f=1}END{for(i in c)print c[i]b i b e[i]g[i]b}' test_new.csv
    Résultat obtenu
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    1;123456789;FR12345;DUPONT;HENRI;12-08-1950;12800;EUR;CARTE;GA;150;DB;20;
    1;842216654;FR8523;LECOMTE;CATHERINE;21-08-1989;43520;EUR;CARTE;GC;25000;DB;15;
    2;9876543210;FR456788;MARTIN;JACQUES;21-08-1902;94250;EUR;CARTE;GA;3600;DB;GC;25000;DB;178;
    1;412566655;FR43333;MARTIN;LUCIEN;20-02-2000;13200;EUR;CARTE;GA;420;DB;1;

    La 1ère ligne du fichier n'est pas prise en compte
    123456789,FR12345,CEXXXXXX,DUPONT,HENRI,12-08-1950,12800,GU,120,EUR,CARTE,CREDIT,11

    La date doit être au format JJ/MM/YYYY, est-ce que je peux le faire dans la même commande awk?

    Merci d'avance

  4. #4
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 283
    Par défaut
    Bonjour

    Citation Envoyé par sandrine06801 Voir le message
    La date doit être au format JJ/MM/YYYY, est-ce que je peux le faire dans la même commande awk?
    Le 6ème champ est modifié. La fonction renvoie le nombre de substitutions. Ici, 2.

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2012
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2012
    Messages : 9
    Par défaut
    Bonjour

    Merci à Flodelarab

    En modifiant la commande, je suis parvenue à ce que la 1ère ligne ne soit plus ignorée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk -F ',' -v b=";" '{$12=$12=="DEBIT"?"DB":"CR";a=$1b$2b$4b$5b$6b$7b$10b$11;++c[a];e[a]=e[a]$8b$9b$12b;g[a]=g[a]+$13} END{for(i in c)print c[i]b i b e[i]g[i]b}' test_new.csv
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    2;123456789;FR12345;DUPONT;HENRI;12-08-1950;12800;EUR;CARTE;GU;120;CR;GA;150;DB;31;
    1;842216654;FR8523;LECOMTE;CATHERINE;21-08-1989;43520;EUR;CARTE;GC;25000;DB;15;
    2;9876543210;FR456788;MARTIN;JACQUES;21-08-1902;94250;EUR;CARTE;GA;3600;DB;GC;25000;DB;178;
    1;412566655;FR43333;MARTIN;LUCIEN;20-02-2000;13200;EUR;CARTE;GA;420;DB;1;

    Si quelqu'un peut m'expliquer la partie f&&NF de la commande communiquée par ctac_, je suis preneuse


    Je vais maintenant essayer de modifier la commande awk pour que la date ait le bon format dans le fichier de sortie

    Merci

  6. #6
    Expert confirmé Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 982
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 982
    Par défaut
    f&&NF avait pour rôle par rapport à ton fichier d'origine (celui de ton premier post) de zapper toutes les lignes avant celles contenant les données (car f passe à 1 une fois le header rencontré) ainsi que les éventuelles lignes vides après (car dans ce cas les nombre de champs NF est égal à 0). Pour résumer la condition f&&NF renvoie 1 que pour les lignes de données.

    Une chose qui m'interroge: Est-il normal d'additionner les crédits et les débits d'Henri Dupont? Ne devrait-on pas les retrancher les uns aux autres et, sur la ligne résultat, décider s'il s'agit d'un crédit ou d'un débit selon le signe du résultat?

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

Discussions similaires

  1. Quelle commande awk pour modifier des fichiers dynamiquement
    Par luna007 dans le forum Shell et commandes GNU
    Réponses: 8
    Dernier message: 04/08/2019, 11h27
  2. Réponses: 0
    Dernier message: 31/01/2019, 20h14
  3. [Batch] script batch pour modifier un fichier pdf
    Par yabo84 dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 05/07/2013, 12h22
  4. Script AWK pour modifier un fichier
    Par leanima dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 13/04/2012, 12h49
  5. Script shell pour modifier plusieurs fichiers
    Par julio_097 dans le forum Shell et commandes GNU
    Réponses: 10
    Dernier message: 03/10/2006, 12h41

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