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 :

Calcul moyenne et division sur le nombre de lignes avec séparateur et avec awk


Sujet :

Shell et commandes GNU

Vue hybride

Shyma Calcul moyenne et division... 04/07/2017, 13h29
BufferBob salut, à voir, mais je... 04/07/2017, 17h05
disedorgue De toute façon, awk ne sait... 04/07/2017, 23h47
Shyma @ disedorgue Tu veux dire... 05/07/2017, 00h13
disedorgue Lorsque awk récupère une... 05/07/2017, 10h32
BufferBob Re : Calcul moyenne et division... 07/07/2017, 00h01
Shyma Alors un exemple de fichier... 07/07/2017, 00h06
BufferBob "separateur" est un mot clé... 07/07/2017, 01h57
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Shyma
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 100
    Par défaut Calcul moyenne et division sur le nombre de lignes avec séparateur et avec awk
    Bonjour,

    J'ai besoin d'aide pour faire des opérations, calculer la moyenne et diviser sur le nombre de ligne qu'il y a entre le séparateur de lignes, qui est différent (separateur1, separateur2 ..... separateurN)
    j'ai mon fichier qui est sous cette forme :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     separateur1
    premier          abc    12 09 6            personne=nom1 17 20;                                               moyenne (20+17)
    premier          abc     11 9  6            personne=nom1 16 19 ;                                                (19+16)
    premier         abc     30 9 15           personne=nom1 14 19 ;                                                 (14+19) =======>Additionner les trois et les diviser sur 3 
    separateur2
     
    deuxième       abc     5 7 9            personne=nom2 15 17  ;                                               (15+17)
    deuxième       abc     56 5 9          personne=nom2 10 20  ;                                                 (10+20)
    deuxième      abc     8 9 4           personne=nom2  8 13;                                                       (13+8)
    deuxième     abc    1 56 7           personne=nom2 5 12 ;                                                        (12+5)  ====> Additionner les 4 et les diviser sur 4

    J'espère que c'est assez clair comme explication.

    Merci

  2. #2
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    à voir, mais je crois que la précédente discussion (identique) a été délaissée parce que personne ne comprenait le problème (ou qu'il n'était pas posé de manière suffisamment claire, au choix)

    l'emploi d'un jargon adéquat (pas obligatoirement technique), les exemples "avant-après", l'utilisation de codes couleurs, se mettre à la place de son interlocuteur pour lequel certaines choses ne coulent pas de source etc. sont autant d'outils pour se faire comprendre, et par corolaire se faire aider

    pour le moins, le fichier que tu donnes en exemple est mal formatté (des espaces un peu partout, pas sur chaque ligne etc.), on est d'accord que c'est volontaire et que ça reflète bien le fichier tel qu'il peut réellement être ?
    aussi tu donnes le fichier de départ, est-ce que sur la base de ce même fichier tu peux donner l'exemple de fichier d'arrivée/en sortie ?
    toute précision complémentaire sera évidement la bienvenue, mieux vaut trop que pas assez en l'occurrence

  3. #3
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 343
    Par défaut
    De toute façon, awk ne sait pas évaluer une chaîne de caractère de type mathématique comme par exemple (20+17).

  4. #4
    Membre confirmé Avatar de Shyma
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 100
    Par défaut
    @ disedorgue
    Tu veux dire quoi avec ta réponse ?

  5. #5
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 343
    Par défaut
    Lorsque awk récupère une donnée dans un fichier, il considère celle-ci comme une chaine de caractère et de ce fait, quand il récupère (20+17), il ne voit que la chaine de caractère et non la donnée arithmétique, il ne saura donc pas l'évaluer.

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 102
    Par défaut
    Pas chez moi!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ echo "17 20" | awk '{print $1+$2}'
    37
    $ awk --version
    awk version 20070501
    À moins que tu ne veuilles dire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ echo "17+20" | awk '{print $1}'
    17+20
    mais ce n'est pas le cas dans le travail demandé

  7. #7
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    Citation Envoyé par BufferBob Voir le message
    tu donnes le fichier de départ, est-ce que sur la base de ce même fichier tu peux donner l'exemple de fichier d'arrivée/en sortie ?

  8. #8
    Membre confirmé Avatar de Shyma
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 100
    Par défaut
    Alors un exemple de fichier de sortie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    separateur1   2
    premier          abc    12 09 6            personne=nom1 17 20;                                              
    premier          abc     11 9  6            personne=nom1 16 19 ;                                                
    premier         abc     30 9 15           personne=nom1 14 19 ;                                         
    separateur2   7
     
    deuxième       abc     5 7 9            personne=nom2 5 17  ;                                           
    deuxième       abc     56 5 9          personne=nom2 10 20  ;                                               
    deuxième      abc     8 9 4           personne=nom2  8 13;                                                       
    deuxième     abc    1 56 7           personne=nom2 5 12 ;

  9. #9
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    • "separateur" est un mot clé en début de ligne qui délimite un le commencement d'un nouveau bloc, et la fin du bloc précédent
    • les lignes vides n'ont pas de signification et sont à ignorer
    • chaque ligne d'un bloc (hors ligne contenant le mot "separateur") se termine par 2 nombres (appelons les titi et toto), suivi d'un point-virgule "un peu encombrant"
    • le but étant pour chaque bloc, d'ajouter à la suite de la ligne separateur la différence entre le dernier toto du bloc et le premier titi de ce même bloc


    ça n'a rien de simple notamment dû au fait qu'il faut stocker des valeurs pour les utiliser plus tard, réécrire des lignes déjà passées etc.
    la seule solution que je vois c'est à coups de awk et en stockant l'intégralité du fichier en mémoire (un tableau de lignes), à la fin on affiche le nouveau fichier à l'écran

    en pseudo-code :
    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
    si on voit "separateur" {
       si c'est la première fois {
          on ne fait rien, on stocke juste la position de ce séparateur pour pas l'oublier
       } sinon {
          on modifie la ligne du précédent séparateur en lui rajoutant (dernier toto - premier titi) en bout de ligne
       }
       dans tous les cas on passe de l'état 0 à l'état 1, et on s'arrête là, on va lire une autre ligne dans le fichier
    }
    
    si on est en état 1 {
       dans ce cas on récupère l'avant dernier nombre: c'est le premier titi du bloc, et on repasse à l'état 0
    } sinon {
       pour chaque ligne qu'on lit, on garde le dernier nombre de la ligne, c'est le dernier toto en date
       et lorsqu'on arrivera sur le séparateur ce sera même le dernier toto de tout le bloc
    }
    en awk :
    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
    #!/usr/bin/awk -f
    BEGIN {
       first_time = 1;                                 # 1ere fois quon voit le separateur ? on pourrait sen passer, juste question de lisibilité...
    }
     
    {
       line[cpt] = $0;                                 # on stocke chaque ligne dans un tableau
    }
     
    /^[ \t]*$/ {                                       # on zappe les lignes vides, mais on veut les garder pour affichage à la fin
       cpt++;
       next;
    }
     
    /^separateur/ {                                    # si on voit le séparateur
       if (first_time) {                               # si cest la première fois
          first_time = 0;
       } else {                                        # sinon on modifie le séparateur précédent
          line[last_sep] = line[last_sep] "   " last_toto - first_titi;
       }
       state++
       last_sep = cpt;
       cpt++;
       next;
    }
     
    state == 1 {                                       # on récupère le premier titi du bloc
       gsub(/[ \t]*;[ \t]*$/,"",$0);
       first_titi = $(NF-1);
       state = 0;
    }
     
    {                                                  # sur les autres lignes on récupère toto, dernier arrivé = dernier toto du bloc
       gsub(/[ \t]*;[ \t]*$/,"",$0);
       last_toto = $NF;
       cpt++;
    }
     
    END {                                              # à la fin on affiche tout le fichier
       line[last_sep] = line[last_sep] "   " last_toto - first_titi;  # on oublie pas de modifier la dernière ligne de séparateur
       for(i = 0; i < cpt; i++) {
          print line[i];
       }
    }
    et le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $ ./script.awk fichier
     
    separateur1   2
    premier          abc    12 09 6            personne=nom1 17 20;
    premier          abc     11 9  6            personne=nom1 16 19 ;
    premier         abc     30 9 15           personne=nom1 14 19 ;
    separateur2   7
     
    deuxième       abc     5 7 9            personne=nom2 5 17  ;
    deuxième       abc     56 5 9          personne=nom2 10 20  ;
    deuxième      abc     8 9 4           personne=nom2  8 13;
    deuxième     abc    1 56 7           personne=nom2 5 12 ;
    (note que le fichier en entrée que tu as fourni contenait une ligne vide en début de fichier, on la retrouve ici à l'identique)

  10. #10
    Membre confirmé Avatar de Shyma
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2015
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2015
    Messages : 100
    Par défaut
    Bonjour

    J'ai essayé ton code @BufferBob, mais cela ne marche pas pour moi. cela m'affiche des erreurs.

    Du coup je voudrais afficher ces valeurs là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
      
    separateur1  
    premier          abc    12 09 6            personne=nom1 17 20;                                              
    premier          abc     11 9  6            personne=nom1 16 19 ;                                                
    premier         abc     30 9 15           personne=nom1 14 19 ;                                         
    separateur2  
     
    deuxième       abc     5 7 9            personne=nom2 5 17  ;                                           
    deuxième       abc     56 5 9          personne=nom2 10 20  ;                                               
    deuxième      abc     8 9 4           personne=nom2  8 13;                                                       
    deuxième     abc    1 56 7           personne=nom2 5 12 ;
    Pour avoir ce fichier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    separateur1   17 19
    premier          abc    12 09 6            personne=nom1 17 20;                                              
    premier          abc     11 9  6            personne=nom1 16 19 ;                                                
    premier         abc     30 9 15           personne=nom1 14 19 ;                                         
    separateur2   5 12
     
    deuxième       abc     5 7 9            personne=nom2 5 17  ;                                           
    deuxième       abc     56 5 9          personne=nom2 10 20  ;                                               
    deuxième      abc     8 9 4           personne=nom2  8 13;                                                       
    deuxième     abc    1 56 7           personne=nom2 5 12 ;

Discussions similaires

  1. Count sur un nombre de lignes d'un CSV
    Par Vlad69 dans le forum Développement de jobs
    Réponses: 1
    Dernier message: 07/10/2013, 13h32
  2. Réponses: 3
    Dernier message: 07/12/2011, 17h22
  3. Calcul sur le nombre de ligne
    Par Chikatilo dans le forum VBA Access
    Réponses: 6
    Dernier message: 06/07/2008, 13h45
  4. Réponses: 2
    Dernier message: 02/10/2006, 11h45
  5. Réponses: 35
    Dernier message: 10/05/2006, 01h11

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