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 :

compter ou récupérer des champs même vides


Sujet :

Shell et commandes GNU

  1. #1
    Membre du Club
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 41
    Points
    41
    Par défaut compter ou récupérer des champs même vides
    Bonjour !
    J'ai besoin de compter les champs d'un fichier séparés par des tabulations.
    Par exemple avec ce fichier contact :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    nom	tel	cp	ville
    DUPONT		13100	MARSEILLE
    DUPONT	0123456		MARSEILLE
    DURAND			
    TINTIN
    Pour extraire les champs j'utilise le script suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/bin/bash
    cat $1 | while read ligne
    do
      i=0
      for champ in $ligne
      do
        i=$(( $i + 1 ))
        echo Champ n°$i : $champ
      done
    done
    Problème : ce script retrouve 1 ou 3 champs par ligne, alors que les deux premières comprennent 4 champs séparés par des tabulations. Le champ vide est donc ignoré.
    La commande cut -f $n permet bien d'extraire chaque champ y compris les champs vides mais il faut indiquer le numéro du champs. Il faudrait alors faire une boucle pour compter le nombre de champs, car sinon la boucle s'arrêtera à la fin du fichier et non pas de la ligne... là encore je ne sais pas comment faire.

    Merci de l'aide,
    Thibaud.

  2. #2
    Membre éclairé Avatar de BlaireauOne
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    492
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2007
    Messages : 492
    Points : 652
    Points
    652
    Par défaut
    Avec awk, rien de plus simple

    http://www.shellunix.com/awk.html
    http://lea-linux.org/cached/index/Dev-awk.html


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    awk -F"\t" '{ print "Enr.", NR, "à", NF, "champ(s)" } ' contact
    Résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Enr. 1 à 4 champ(s)
    Enr. 2 à 4 champ(s)
    Enr. 3 à 4 champ(s)
    Enr. 4 à 4 champ(s)
    Enr. 5 à 1 champ(s)

  3. #3
    Membre du Club
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 41
    Points
    41
    Par défaut
    Merci pour awk ! Effectivement ça m'a permis d'avancer... Hélas, je retombe sur le même souci, car awk m'indique le nombre de champs seulement pour des fichiers, pas pour une chaîne dans une variable... ?

  4. #4
    Membre du Club
    Inscrit en
    Mars 2008
    Messages
    80
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 80
    Points : 41
    Points
    41
    Par défaut
    Bon, j'ai fait quand même avec awk en utilisant un fichier tampon.
    Le problème qui subsiste, c'est d'indiquer de NE PAS fusionner certains champs ; donc qu'il existe des clés, par exemple la colonne "nom à afficher" dans thunderbird.
    En effet, si j'ai mon fichier ressemble à ceci :
    NOM Mail
    Dupont
    tintin@herge.com
    Le script va donc mélanger fusionner ces deux lignes, alors qu'il s'agit de deux personnes différentes !
    Si vous avez des idées...
    Alors le voici :
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    #!/bin/bash
    ###
    ## Ce programme fusionne les champs d'un tableur au format csv
    ## lancer le programme comme suit :
    ## sh fusionne_champs.sh nom_du_fichier "caractère de séparation"
    ## le caractère peut être une tabulation : "\"
    #######
     
     
    # Paramètres :
    fic=$1 # fic contenant les enregistrements
    sep=$2 # separateur de ch_act
     
    ## VARIABLES ##
    pre="" # ligne précedente à ch_prearer
    act="" # ligne actuelle
    suiv="" # ligne suivante
    fusion="" # ligne fusionnée
    diff=0
    log="$(echo fusion\.$(date +%G%m%d%H%M)\.log)"
    echo $log
    # Initialise les fichiers
    if [ -e new ] # fichier de sortie
    then
    	rm new
    fi
    if [ -e tampon_pre ] # fichier de sortie
    then
    	rm tampon_pre
    fi
    if [ -e tampon_act ] # fichier de sortie
    then
    	rm tampon_act
    fi
    if [ -e $log ] # fichier de sortie
    then
    	rm $log
    fi
    touch $log
     
    ## PROGRAMME ##
    nb_enr=$(wc -l $fic|cut -d " " -f 1)
    for ((enr=1 ; enr <= nb_enr ; enr++))
    do
    echo -e "$enr/$nb_enr"
    #	echo $enr.
    	pre="$act"
    	act=$(awk -F"$sep" 'NR == '$enr' {print $0}' $fic)
    	if [ -n "$pre" ]
    	then
    		echo "$pre">tampon_pre
    		echo "$act">tampon_act
    #		nb_act=$(awk -F "$sep" 'NR == '$enr' { print NF } ' $fic) #nb de ch_act dans la ligne act.
    #		nb_pre=$(awk -F "$sep" 'NR == '$(($enr - 1))' { print NF } ' $fic) #nb de ch_act dans la ligne préc. à ch_prearer
    		nb_act=$(awk -F "$sep" '{ print NF } ' tampon_act) #nb de ch_act dans la ligne act.
    		nb_pre=$(awk -F "$sep" '{ print NF } ' tampon_pre) #nb de ch_act dans la ligne préc. à ch_prearer
    #echo -e "nb_act : $nb_act \nnb_pre : $nb_pre"
    		fusion=""
    		if [ "$nb_act" -gt "$nb_pre" ]
    		then
    			max=$nb_act
    		else
    			max=$nb_pre
    		fi
    		for ((c=1 ; c <= max ; c++))
    		do
    			if [ $c -gt $nb_pre ]
    			then
    				ch_pre=""
    			else
    				ch_pre=$(echo -e "$pre" |cut -f $c -d "$(echo -e "$sep")")
    			fi
    			if [ $c -gt $nb_act ]
    			then
    				ch_act=""
    			else
    				ch_act=$(echo -e "$act" |cut -f $c -d "$(echo -e "$sep")")
    			fi
    #			echo -e "  $c/$max -Je compare $ch_act (act) avec $ch_pre (pre)"
    			if [ -n "$ch_act" ]
    			then
    				fusion=$(echo -e "$fusion$ch_act$sep")
    			else
    				fusion=$(echo -e "$fusion$ch_pre$sep")
    			fi
    			if [ -n "$ch_act" ]
    			then
    				if [ -n "$ch_pre" ]
    				then
    					c1=$(echo $ch_pre|tr -s a-z A-Z)
    					c2=$(echo $ch_act|tr -s a-z A-Z)
    					if [ "$c1" != "$c2" ]
    					then		
    						diff=1 # les enregistrements sont différents
    						c=$max	
    					fi
    				fi
    			fi
    		done
    		if [ $diff = 0 ]
    		then # enregistrements fusionnés
    #				$fusion=$(echo -e "$fusion" |sed -e "s/"$sep"$//g") # Pb non réglé de suppression de tabulation en fin de ligne
    			echo "$fusion" >> $log
    			act="$fusion"
    		else # enregistrements différents
    			echo -e "$pre" >> new
    			diff=0
    #			echo -e \=\> "$act est différent de $pre\n"
    		fi
    	fi
    done
     
     
    if [ $diff = 0 ] # s'il n'y a pas eu de fusion
    then
    	echo $act >>new
    #	echo Ajout suite à fusion de : $act
    fi
     
     
    ## RESULTATS ##
    echo -e "\n"-----------------------------
    echo $(wc -l new)
    #cat new
    echo $(wc -l $fic)
    #cat f
    echo $(wc -l $log)
    #cat "$log"

Discussions similaires

  1. Vérifier si des champs sont vides
    Par Colbix dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 07/08/2007, 19h36
  2. Récupérer des champs d'un fichier
    Par ostenx dans le forum GTK+ avec C & C++
    Réponses: 1
    Dernier message: 27/06/2007, 09h38
  3. Réponses: 2
    Dernier message: 08/06/2007, 18h00
  4. [SQL] Comment récupérer des champs a partir d'un fichier de sauvegarde?
    Par baguira dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 15/03/2007, 18h23
  5. Moyenne des champs non vide dans un état
    Par loutsky dans le forum Access
    Réponses: 4
    Dernier message: 05/04/2006, 17h26

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