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 :

Modifier plusieurs champs dans un fichier Csv


Sujet :

Shell et commandes GNU

  1. #21
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    792
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 792
    Points : 1 206
    Points
    1 206
    Par défaut
    Citation Envoyé par francois_a Voir le message
    Ripat :
    Alors je suis sur une machine virtuelle qui tourne sous Debian version 5.0.2, mais mon script devra tourner sous une Red Hat et/ou une Mandriva. A priori, je tourne sous mawk version 1.3.3.

    L’erreur que j’ai, c’est « awk : line1 : syntax error at or near print ». Je n’ai plus d’erreur quand je mets un ; avant le print je n’ai aucun résultat.
    Pas d'erreurs chez moi. Pourrais-tu poster le code (m)awk que tu exécutes?
    :q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp
    :quitplease :quitnow :leave :shit ^X^C ^C ^D ^Z ^Q QUITDAMMIT
    Jabber: ripat at im.apinc.org

  2. #22
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2009
    Messages : 72
    Points : 45
    Points
    45
    Par défaut
    Je te recopie le code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    chemin='/home/francois/Desktop/test.csv'
    nouveaufichier='/home/francois/Desktop/temp'
     
    > $nouveaufichier
     
    awk 'Begin{FS=OFS=";" split ("3-4", p, "-")}{for (i in p) $p[i]?$p[i]:"xx" print > "$nouveaufichier"}' "$chemin"
    J'ai vérifié que mes espaces n'avaient pas été fait avec la touche Alt Gr.

  3. #23
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    792
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 792
    Points : 1 206
    Points
    1 206
    Par défaut
    Ah ok., si tu mets tout sur une ligne, tu dois effectivement mettre un ; pour terminer la structure for() avant le print de l'instruction suivante.

    Sur plusieurs lignes comme dans mon post plus haut, la fin de ligne termine l'instruction.

    Essaye d'abord en dirigant le print vers la console:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk 'BEGIN{FS=OFS=";" split ("3-4", p, "-")}{for (i in p) $p[i]?$p[i]:"xx"; print}' fichier_test
    Si le résultat te convient, dirige le print vers un fichier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk 'BEGIN{FS=OFS=";" split ("3-4", p, "-")}{for (i in p) $p[i]?$p[i]:"xx"; print > "fichier_out"}' fichier_test
    :q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp
    :quitplease :quitnow :leave :shit ^X^C ^C ^D ^Z ^Q QUITDAMMIT
    Jabber: ripat at im.apinc.org

  4. #24
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2009
    Messages : 72
    Points : 45
    Points
    45
    Par défaut
    décidément quand çà veut pas...

    J'ai testé la 1ere ligne, elle ne modifie rien ! aucun champ vide ne se remplit

    par contre je n'ai plus d'erreur !

  5. #25
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Citation Envoyé par francois_a Voir le message
    jabbounet/N_Bah :
    Je ne m'étais pas aperçu que le script ne fonctionnait pas correctement.

    En effet, avec un fichier de départ qui ressemble à çà :
    aa;bb;;;
    aa;bb;;dd;
    aa;bb;cc;;

    J'obtiens ceci :

    aa;bb;xx;xx; <= ok
    aa;bb;dd;xx; <= pas ok, mon champ est décalé
    aa;bb;cc;xx;xx; <= un champ est ajouté
    en fait les champs vide ne semblent pas être pris en compte avec printf,
    maintenant que j'ai un shell sous la main
    voici une solution possible (basée sur la version bash)
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    #!/bin/bash
     
    No_champs=( 2 3 ) # soit les n° des champs souhaités moins un : les arrays commencent à 0
     
    echo "aa;bb;;;"   > fichier.csv
    echo "aa;bb;;dd"  >> fichier.csv
    echo "aa;bb;cc;;" >> fichier.csv
    echo ";;;;"       >> fichier.csv
    echo ";;"         >> fichier.csv
    echo ";;;d;z" >> fichier.csv
     
    > fichiercible.csv
    while read ligne
     do
       IFS=";" read -a Champs <<< "$ligne"
     
       ##echo "Ligne lue ${Champs[*]}"
       taille=${#Champs[*]}
       ##echo "Taille de la ligne $taille"
     
       for indice in ${No_champs[@]}  
        do
           ## Evite d'insérer des élément quand ils sont non existant à l'origine
           if [ $indice -le $taille ]
           then
               test -z ${Champs[indice]} && Champs[indice]="xx"
           fi
       done
     
       ## Comparé a printf cela permet de prendre en compte les champs
       ## vide du tableau qui n'apparaissait pas avec printf. 
       for indice in "${!Champs[@]}"
       do 
           if [ $indice -eq 0 ]
           then
               var="${Champs[$indice]}"
           else
               var="$var;${Champs[$indice]}"
           fi
       done
       echo "$var" >> fichiercible.csv
     
    done < fichier.csv
    Ce qui donne
    Test fichier format unix
    1,6c1,6
    < aa;bb;;;
    < aa;bb;;dd
    < aa;bb;cc;;
    < ;;;;
    < ;;
    < ;;;d;z
    ---
    > aa;bb;xx;xx
    > aa;bb;xx;dd
    > aa;bb;cc;xx
    > ;;xx;xx
    > ;;xx
    > ;;xx;d;z
    Test fichier format Dos
    1,6c1,6
    < aa;bb;;;

    < aa;bb;;dd

    < aa;bb;cc;;

    < ;;;;

    < ;;

    < ;;;d;z

    ---
    > aa;bb;xx;xx;

    > aa;bb;xx;dd

    > aa;bb;cc;xx;

    > ;;xx;xx;

    > ;;
    ;xx
    > ;;xx;d;z
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  6. #26
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2009
    Messages : 72
    Points : 45
    Points
    45
    Par défaut
    OK merci jabbounet. le code marche tres bien ! Je vais essayer de comprendre le script ! encore merci

    Maintenant j'aimerai qd même comprendre pourquoi le script awk ne fonctionne pas !

  7. #27
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    j'utilise rarement awk même s'il est très puissant mes connaissances le concernant sont très limités.

    pour les trucs compliqué sur les fichiers texte j'utilise perl en général.
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  8. #28
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2009
    Messages : 72
    Points : 45
    Points
    45
    Par défaut
    J'avoue que je ne connais pas trop pearl.

    Le script que je suis en train de réaliser va lancer des scripts en pearl déjà fait pour certaines parties de la procédure que j'automatise.
    J'ai essayé de faire un script global mais vu qu'ils ne sont pas commentés... Ils sont illisible pour moi, même avec un book et internet.

    En tout cas je te remercie pour ton (votre) aide !

  9. #29
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2009
    Messages : 72
    Points : 45
    Points
    45
    Par défaut
    bon j'ai regardé ton script jabbounet et il a certaine chose que je ne comprends pas.

    Je ne comprends pas ces commandes :

    "<<<" je ne connais que << et < respectivement utilise l'entrée standard comme flux et utilise un fichier comme entrée standard

    Le "#" dans taille=${#Champs[*]}, pour moi # permettait de faire des commentaires...
    [Je viens de trouver, à priori çà renvois la valeur du nb total de champs]

    Je suppose que le "*" signifie que l'on appelle l'ensemble du tableau.

    Le "@" dans No_champs[@] correspond à l'ensemble des valeurs ? (on pourrait le remplacer par No_champ[ 2 3 ].

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 539
    Points : 19 361
    Points
    19 361
    Par défaut
    <<< c'est en quelque sorte un "mini here-doc". très pratique pour éviter des formes lourdes telles que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    echo "tra la lère" | commande ...
    # on fait l'économie d'une commande(?)
    commande ... <<< "tra la lère"
    # ça fonctionne avec les variables
    commande ... <<<"$var"
    quant au # dans les variables et tableaux, mais tu as déjà compris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    var="tra la lère"
    echo ${#var}
    11
    var=(tra la lère)
    echo ${#var[@]}
    3
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #31
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Citation Envoyé par francois_a Voir le message
    bon j'ai regardé ton script jabbounet et il a certaine chose que je ne comprends pas.

    Je ne comprends pas ces commandes :

    "<<<" je ne connais que << et < respectivement utilise l'entrée standard comme flux et utilise un fichier comme entrée standard

    Le "#" dans taille=${#Champs[*]}, pour moi # permettait de faire des commentaires...
    [Je viens de trouver, à priori çà renvois la valeur du nb total de champs]

    Je suppose que le "*" signifie que l'on appelle l'ensemble du tableau.

    Le "@" dans No_champs[@] correspond à l'ensemble des valeurs ? (on pourrait le remplacer par No_champ[ 2 3 ].
    pas mal de réponse concernant la manipulation des tableaux en bash ici
    http://tldp.org/LDP/abs/html/arrays.html
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  12. #32
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2009
    Messages : 72
    Points : 45
    Points
    45
    Par défaut
    Bon j'ai un prob avec ton script jabbounet. Il me tronque les champs supérieur au champ max contenu dans No_Champ. Ce que je ne comprends pas car je pensais que ce bout de code lisait tous les indices sauf ceux modifiés...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    for indice in "${!Champs[@]}"
    Il faudrait peut être que je fasse une boucle while qui lise tout les indices en utilisant $taille comme limitateur ?

  13. #33
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2009
    Messages : 72
    Points : 45
    Points
    45
    Par défaut
    Merci pour le lien
    J'avais trouvé ici http://www.trustonme.net/didactels/148.html et http://www.epons.org/shell-bash-variables.php

    Par contre, je ne trouve pas concernant "<<<"

  14. #34
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Citation Envoyé par francois_a Voir le message
    Merci pour le lien
    J'avais trouvé ici http://www.trustonme.net/didactels/148.html et http://www.epons.org/shell-bash-variables.php

    Par contre, je ne trouve pas concernant "<<<"
    ici tu as la réponse:
    http://www.gnu.org/software/bash/man...redirection-98


    3.6.6 Here Documents

    This type of redirection instructs the shell to read input from the current source until a line containing only word (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input for a command.

    The format of here-documents is:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
         <<[]word
                 here-document
         delimiter
    No parameter expansion, command substitution, arithmetic expansion, or filename expansion is performed on word. If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. In the latter case, the character sequence \newline is ignored, and ‘\’ must be used to quote the characters ‘\’, ‘$’, and ‘`’.

    If the redirection operator is ‘<<-’, then all leading tab characters are stripped from input lines and the line containing delimiter. This allows here-documents within shell scripts to be indented in a natural fashion.

    3.6.7 Here Strings

    A variant of here documents, the format is:
    The word is expanded and supplied to the command on its standard input.
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  15. #35
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2009
    Messages : 72
    Points : 45
    Points
    45
    Par défaut
    Désolé je n'avais pas vu le message de N_BaH

    ok Merci pour les infos

  16. #36
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    792
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 792
    Points : 1 206
    Points
    1 206
    Par défaut
    Citation Envoyé par francois_a Voir le message
    décidément quand çà veut pas...

    J'ai testé la 1ere ligne, elle ne modifie rien ! aucun champ vide ne se remplit

    par contre je n'ai plus d'erreur !
    Ça m'a échappé mais tu as fait 2 autres erreurs de retranscription de mon code. A nouveau, si tu mets plusieurs lignes de code awk sur une seule, tu dois terminer chaque instruction par un ;. Regarde à nouveau mon exemple ici:
    http://www.developpez.net/forums/m4603577-12/

    De plus, en remettant sur une seule ligne tu as oublié un élément essentiel dans la condition ternaire, c'est l'affectation du résultat de <cond>?<valeur si vrai>:<valeur si faux> au champ $n.

    Si on remet ça sur une seule ligne, ça doit donner ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     awk 'BEGIN{FS=OFS=";";split("3-4", p, "-")} {for (i in p) $p[i]=$p[i]?$p[i]:"xx";print}' fichier.test
    Ou bien tu reprends mon code sur plusieurs lignes dans mon post plus haut. Je te le recommande d'ailleurs, pour des raisons de lisibilité. Les one-liner, ça fait bien dans un forum mais après, quand il faut se relire...

    Testé sur un fichier.test:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ cat fichier.test 
    aa;bb;;;
    aa;bb;;dd
    aa;bb;cc;;
    :q :q! :wq :w :w! :wq! :quit :quit! :help help helpquit quit quithelp
    :quitplease :quitnow :leave :shit ^X^C ^C ^D ^Z ^Q QUITDAMMIT
    Jabber: ripat at im.apinc.org

  17. #37
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2009
    Messages : 72
    Points : 45
    Points
    45
    Par défaut
    ripat :

    Ton script fonctionne parfaitement chez moi.

    (Il faut vraiment que je regle ce prob d'internet sur ma machine virtuelle pour faire des copier/coller et que j'aille voir l'ophtalmo pour mes yeux ).

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Modifier un champ dans un fichier texte
    Par Klyre dans le forum LabVIEW
    Réponses: 7
    Dernier message: 03/06/2015, 15h28
  2. [CSV] Insérer des champs dans un fichier CSV
    Par floctc dans le forum Langage
    Réponses: 1
    Dernier message: 20/07/2009, 12h26
  3. spool plusieurs requète dans même fichier csv
    Par hichcasa dans le forum Sql*Plus
    Réponses: 1
    Dernier message: 02/03/2009, 13h27
  4. [CSV] Modifier un champ d'un fichier CSV
    Par BernardT dans le forum Langage
    Réponses: 3
    Dernier message: 04/07/2007, 11h13
  5. Réponses: 3
    Dernier message: 26/04/2006, 12h52

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