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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    72
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2009
    Messages : 72
    Par défaut Modifier plusieurs champs dans un fichier Csv
    Bonjour à tous,

    Je fais un script pour automatiser des taches administratives sous linux.
    Actuellement, je bloque sur un problème de modification de champs. Je ne vois pas d'où cela vient.

    Je souhaite remplacer certain champs vide par XX. Pour l'exemple, je n'utilise que de champs mais mes lignes contiennent 40 champs. Je dois en modifier une petite dizaine.

    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
     
    #!/bin/bash
     
    ...
    # création du fichier et initialisation de la variable tmp
    echo > $nouveau fichier
    tmp=''
     
    # Lecture du fichier ligne par ligne
    for ligne in $(cat test.csv)
    do
    # Modification des champs 3 et 4
    for c in 3 4 ;
    do
     
    # Selectionne une cellule
    cel=$(echo $ligne | awk -F";" '{print $'$c'}')
     
    # Test de la cellule
    if [[ "$cel" == "" ]]
       then # Elle vide, j'atribue XX
              tmp=$(echo $ligne | awk -F";" 'BEGIN { OFS=";" }{$'sc'="XX"; print $0}')
              echo $tmp >> $nouveaufichier
              cat $nouveaufichier > test.csv
              tmp=''
    fi
    done
    done
    le fichier test.csv avant
    aa;bb;;;
    aa;bb;;dd,
    aa;bb;cc;;

    le resultat :

    aa;bb;xx;;
    aa;bb;;xx;
    aa;bb;xx;dd,
    aa;bb;cc;xx;

    2 problèmes apparaissent :
    Une première ligne vide (je ne vois pas d'où elle sort.
    le resultat pour la ligne aa;bb;;; qui devrait etre aa;bb;xx;xx;

    Quelqu'un voit-il le problème dans mon code ?

    merci d'avance

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    Heu...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    cat francois_a.dat
    aa;bb;;;
    aa;bb;;dd,
    aa;bb;cc;;
     
    sed ':boucle1; s/;;/;xx;/; t boucle1' francois_a.dat
    aa;bb;xx;xx;
    aa;bb;xx;dd,
    aa;bb;cc;xx;
    non ?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

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

    Informations forums :
    Inscription : Juillet 2009
    Messages : 72
    Par défaut
    Oui j'étais parti sur cette solution au départ. Une bonne ligne en sed et c'était réglé.
    Mais car il y a un mais, certain champs doivent rester vide.

    Par contre je ne vois pas à quoi correspond ce qui encadre s/;;/;xx;/;

    :boucle1; et t boucle1

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    si une substitution est opérée, t redirige vers le label boucle1 répéré par les :
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    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 : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Une première ligne vide (je ne vois pas d'où elle sort.
    ici peu etre...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/bin/bash
    
    ...
    # création du fichier et initialisation de la variable tmp
    
    echo > $nouveau fichier
    
    tmp=''
    ....

    pour avoir un fichier vraiment vide tu peux utiliser juste (sans l'echo)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    > nouveauFichier.txt

  6. #6
    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 : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Autrement

    As-tu penser a utiliser IFS pour parser tes lignes?

    petit exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #!/bin/bash
    IFS=$','
    vals='/mnt,/var/lib/vmware/VirtualMachines,/dev,/proc,/sys,/tmp,/usr/portage,/var/tmp'
    for i in $vals; do echo $i; done
    unset IFS
    et set -x pour tracer l'execution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    set -x
    .... le code que je veux tracer
    set +x

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

    Informations forums :
    Inscription : Juillet 2009
    Messages : 72
    Par défaut
    Merci pour le echo !!! Je suis tête en l'air par moment !!!

    Sinon concernant IFS, je ne vois pas trop l'intérêt.

    J'ai une idée mais je ne sais pas comment la mettre en oeuvre.

    Il me semble que lorsque l'on utilise un pipe les variables reste les même.
    Mon idée serai de faire un script qui renverrai çà :
    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
     
    #!/bin/bash
     
    ...
    # création du fichier et initialisation de la variable tmp
    > $nouveau fichier
    tmp=''
     
    # Lecture du fichier ligne par ligne
    for ligne in $(cat test.csv)
    do
    # Modification des champs 3 et 4
    tmp=$(echo $ligne |for c in 3 4 ;
             do
     
            # Selectionne une cellule
            cel=$(echo $ligne | awk -F";" '{print $'$c'}')
     
            # Test de la cellule
            if [[ "$cel" == "" ]]
               then # Elle vide, j'atribue XX
                       awk -F";" 'BEGIN { OFS=";" }{$'sc'="XX"; print $0}')
                      echo $tmp >> $nouveaufichier
                      cat $nouveaufichier > test.csv
                      tmp=''
            fi
            done)
    done

    bien sur j'ai testé et çà ne passe pas

  8. #8
    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 : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Un truc comme ça (je n'ai pas de shell sous la main, mais l'esprit y est)
    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
     
    #!/bin/bash
     
    ...
    # création du fichier et initialisation de la variable tmp
    > $nouveau fichier
    tmp=''
     
    # Lecture du fichier ligne par ligne
    for ligne in $(cat test.csv)
    do
    # Modification des champs 3 et 4
    IFS=;
    echo "$line" | read array[1] array[2] array[3] array[4] array[5] 
    IFS=" "
     
      for index in 3 4 
      do
         if [[ "X${array[index]" == "X" ]]
         then
            array[index]="XX"
         fi
      done 
    echo "${array[1]};${array[2]};....." > fichiercible.csv
    done
    mes deux sources d'inspiration pour cette idée
    http://www.linuxtopia.org/online_boo...de/arrays.html
    http://www.unix.com/shell-programmin...tion-bash.html

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 664
    Par défaut
    Ah, ouais... !

    Je me permet de 'transcrire' ce que, s'il avait eu un shell, Jabbounet aurait écrit :
    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
    #!/bin/bash
    
    No_champs=( 2 3 ) # soit les n° des champs souhaités moins un : les arrays commencent à 0
    
    while read ligne
     do
       IFS=";" read -a Champs <<< "$ligne"
    
       for indice in ${No_champs[@]}  
        do
          test -z ${Champs[indice]} && Champs[indice]="xx"
       done
    
       var=$(printf '%s;' ${Champs[@]})
       echo "$var" >> fichiercible.csv
    
    done < fichier.csv
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

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

    Informations forums :
    Inscription : Mai 2004
    Messages : 792
    Par défaut
    Un one-liner awk:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk 'BEGIN{FS=OFS=";"}{$3=$3?$3:"xx";$4=$4?$4:"xx"}1' fichier

  11. #11
    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 : 49

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    Ah, ouais... !

    Je me permet de 'transcrire' ce que, s'il avait eu un shell, Jabbounet aurait écrit :
    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
    #!/bin/bash
    
    No_champs=( 2 3 ) # soit les n° des champs souhaités moins un : les arrays commencent à 0
    
    while read ligne
     do
       IFS=";" read -a Champs <<< "$ligne"
    
       for indice in ${No_champs[@]}  
        do
          test -z ${Champs[indice]} && Champs[indice]="xx"
       done
    
       var=$(printf '%s;' ${Champs[@]})
       echo "$var" >> fichiercible.csv
    
    done < fichier.csv
    merci , c'est même plus joli que ce que j'aurais fait

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

Discussions similaires

  1. Modifier un champ dans un fichier texte
    Par Klyre dans le forum LabVIEW
    Réponses: 7
    Dernier message: 03/06/2015, 14h28
  2. [CSV] Insérer des champs dans un fichier CSV
    Par floctc dans le forum Langage
    Réponses: 1
    Dernier message: 20/07/2009, 11h26
  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, 12h27
  4. [CSV] Modifier un champ d'un fichier CSV
    Par BernardT dans le forum Langage
    Réponses: 3
    Dernier message: 04/07/2007, 10h13
  5. Réponses: 3
    Dernier message: 26/04/2006, 11h52

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