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 GNU Discussion :

Sed - substitution de caractères fichier csv


Sujet :

Shell et commandes GNU

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2014
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Sed - substitution de caractères fichier csv
    Bonjour,

    Dans un script bash, je parse des fichiers csv séparateur ";". Hors j'ai un champ spécifique chaine, qui peut contenir mon séparateur avec un nombre variable d'occurences.

    Exemple:
    aaa;bbb;"C11; C22;C23(cc)";ddd;eee
    fff;ggg;"hhhh1;hhhh3;hhhh4;";iii;jjj
    la position de la chaine dans le fichier est fixe (champ 3 dans l'exemple).
    Mon but, remplacer les séparateurs dans cette chaine, pour permettre un traitement particulier ensuite.

    Résultat attendu:

    aaa;bbb;"C11, C22,C23(cc)";ddd;eee
    fff;ggg;"hhhh1,hhhh3,hhhh4,";iii;jjj
    Remarque:

    J'ai trouvé le moyen de le faire avec awk, mais mon traitement serait simplifié si je trouvais le moyen de le faire avec un sed -i

    Commande awk:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat $file | awk -F\" 'BEGIN {OFS="\""}{gsub(";",",",$2);print}'
    Dans mon script, ça m'obligerait à passer par un fichier intermédiaire pour chaque csv

    La plupart de mes occurrences ont un espace après le séparateur, mais pas tous ...
    Donc la seule commande:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -i 's/; /, /g' *.csv
    ne couvre pas tous les cas.

    Peut-on faire cela avec Sed, j'ai bien du mal à créer une règle délimitant la chaine (entre 2 ") et substituant toutes les occurrences de ; entre "" ..

    Merci de votre aide

  2. #2
    Expert éminent

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Points : 6 276
    Points
    6 276
    Par défaut
    Salut,

    Citation Envoyé par airfox35 Voir le message
    J'ai trouvé le moyen de le faire avec awk, mais mon traitement serait simplifié si je trouvais le moyen de le faire avec un sed -i
    À noter que depuis la version awk 4.1.0, awk intègre la fonction inplace.

    Donc je suppute qu'avec cette version, la commande suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     awk -i inplace -v INPLACE_SUFFIX=.bak -F\" 'BEGIN {OFS="\""}{gsub(";",",",$2);print}' $file
    Devrait le faire

    Honnêtement avec sed je doute qu'on puisse y arriver
    $ man woman
    Il n'y a pas de page de manuel pour woman.

  3. #3
    Expert éminent

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Points : 6 276
    Points
    6 276
    Par défaut
    Citation Envoyé par zipe31 Voir le message
    Honnêtement avec sed je doute qu'on puisse y arriver
    J'aurais mieux fait de tourner 7 fois ma souris autour du clavier avant d'écrire môa

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ cat plop 
    aaa;bbb;"C11; C22;C23(cc)";ddd;eee
    fff;ggg;"hhhh1;hhhh3;hhhh4;";iii;jjj
     
    $ sed ':z;s/\("[^;]*\)[^"];/\1,/;tz' plop 
    aaa;bbb;"C1, C2,C23(cc)";ddd;eee
    fff;ggg;"hhhh,hhhh,hhhh,";iii;jjj
    $ man woman
    Il n'y a pas de page de manuel pour woman.

  4. #4
    Nouveau Candidat au Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2014
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Merci pour ta réponse zipe31! C'est presque bon, ca zappe chaque caractère juste devant le ";" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ cat plop 
    aaa;bbb;"C11; C22;C23(cc)";ddd;eee
    fff;ggg;"hhhh1;hhhh3;hhhh4;";iii;jjj
    
    $ sed ':z;s/\("[^;]*\)[^"];/\1,/;tz' plop 
    aaa;bbb;"C1, C2,C23(cc)";ddd;eee
    fff;ggg;"hhhh,hhhh,hhhh,";iii;jjj

    Bien que je pense comprendre la regexp, le début et la fin m'échappent, si tu as un moment pour décrypter

    Pour info, je suis sur du awk 3.1.3 et pas le droit de mise à jour pour profiter du inline

    Merci!

  5. #5
    Expert éminent

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Points : 6 276
    Points
    6 276
    Par défaut
    Oups

    Et comme ça, c'est mieux ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ sed ':z;s/\("[^;]*[^"]\);/\1,/;tz' plop 
    aaa;bbb;"C11, C22,C23(cc)";ddd;eee
    fff;ggg;"hhhh1,hhhh3,hhhh4,";iii;jjj
    $ man woman
    Il n'y a pas de page de manuel pour woman.

  6. #6
    Nouveau Candidat au Club
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2014
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Magnifique, vraiment je te remercie.

    Je vais tâcher de comprendre maintenant. Le z semble faire référence à un label posé sur le signe ";" , le "t" m'échappe.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 550
    Points : 19 383
    Points
    19 383
    Par défaut
    Bonjour,

    ça m'obligerait à passer par un fichier intermédiaire pour chaque csv
    un même fichier pour tous les CSV, qui sera écrasé à chaque fois, pour, finalement, être supprimé.

    note que sed lui-même utilise un fichier temporaire.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Expert éminent

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Points : 6 276
    Points
    6 276
    Par défaut
    Citation Envoyé par airfox35 Voir le message
    Je vais tâcher de comprendre maintenant. Le z semble faire référence à un label posé sur le signe ";" , le "t" m'échappe.
    :z
    On pause une étiquette (pour branchement futur).


    s/\("[^;]*[^"]\);/\1,/
    Pour la substitution on va jouer avec les sous-expression \(...\) et les références arrières \1.
    Une sous-expression est délimitée par des parenthèses (...), protégées en l'occurrence.

    \("[^;]*[^"]\);
    On cherche une chaîne de caractères débutant par un guillemet double ("), suivi de nimporte quels caractères hormis le caractère point virgule ([^;]*) et hormis le guillemet fermant ([^"]).

    \1,
    Quand la chaîne a été trouvée, on la substitue par elle même \1 suivie d'une virgule.


    t z
    Banchement conditionnel (t). Tant qu'une substitution a lieu, alors on se branche à l'étiquette (z).
    $ man woman
    Il n'y a pas de page de manuel pour woman.

Discussions similaires

  1. [commande sed] substitution de caractères
    Par matrix788 dans le forum Linux
    Réponses: 6
    Dernier message: 25/02/2011, 20h33
  2. creer un fichier .csv a partir d'une chaine de caractère
    Par JAMINF dans le forum Général Java
    Réponses: 3
    Dernier message: 31/10/2008, 19h21
  3. Norme fichier .csv : caractère NULL autorisé ?
    Par fumidu dans le forum Excel
    Réponses: 1
    Dernier message: 10/09/2008, 23h15
  4. Réponses: 4
    Dernier message: 29/02/2008, 11h11
  5. import de fichier CSV : problème de caractères accentués
    Par mouaa dans le forum Administration
    Réponses: 2
    Dernier message: 08/08/2007, 07h45

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