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 :

Extraire la moyenne en bash


Sujet :

Shell et commandes GNU

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2022
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Juillet 2022
    Messages : 46
    Par défaut Extraire la moyenne en bash
    Bonjour,

    Je souhaiterais extraire la moyenne chaque groupe (colonne 2),
    puis afficher le nom du fruit (colonne 3) se trouvant le plus proche de la moyenne du groupe.
    J'ai tenté de simplifier le problème.

    groupe.txt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #Groupe Valeur Fruit
      1  8  Orange
      1  6,5  Banane
      1  6 ,2  Pomme 
      1  12  Abricot
      1  7  Mure 
     
      2  4  Pomme
      2  6  Banane
      2  6  Abricot
      2  3  Mure
    (8 + 6 + 6 + 12 +7) / 5 = 7.94
    Le fruit se rapprochant le plus de la moyenne est Orange pour le groupe 1.


    (4 + 6 + 6 + 3) / 4 = 4.75
    Le fruit se rapprochant le plus de la moyenne est Pomme pour le groupe 2.


    Je script un peu en bash mais là je ne sais pas par où commencer. Est ce qu'une personne a une idée ?? ' -_-

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Dorhub Voir le message
    Je script un peu en bash mais là je ne sais pas par où commencer. Est ce qu'une personne a une idée ?? ' -_-
    Oui, des idées on en a.
    Perso, j'écrirais une fonction permettant de calculer la moyenne d'un groupe. On lui passe le groupe (ex 1 ou 2) et elle ressort 7.94. Déjà ça simplifie les choses (juste calculer la moyenne d'un seul groupe, et on l'appelle avec le groupe qu'on veut). Après-tout, ça sert à ça les fonctions (faire un travail unique paramétrable)

    Maintenant la fonction. Premier souci: comment extraire le groupe demandé ? Réponse grep (ou fgrep si possible).
    Ensuite, comment extraire la colonne ciblée d'une info renvoyée par le grep? réponse: cut
    Le reste ce n'est qu'une question d'addition et de division. Petit détail, on est en nombre flottant, les calculs offerts par le shell ne marcheront pas (int). On peut passer par "bc". Exemple echo "1/3" |bc -l.

    Le second travail est de trouver le fruit (du groupe) se rapprochant le plus de la moyenne: pareil, une autre fonction à laquelle on passe le groupe choisi. Cette autre fonction commence par récupérer la moyenne en appelant la première puis le reste ce n'est que de la lecture et soustraction et comparaison du résultat...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2022
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Juillet 2022
    Messages : 46
    Par défaut
    D'accord d'accord, merci pour l'astuce du grep !

  4. #4
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 288
    Par défaut
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ awk '/#|^ *$/{next;} {v[$1]+=$2;n[$1]++;} END{for (i in n) print i,v[i]*1.0/n[i];}' fruits.txt 
    1 7.8
    2 4.75

  5. #5
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2022
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Juillet 2022
    Messages : 46
    Par défaut
    Citation Envoyé par Flodelarab Voir le message
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $  END{for (i in n) print i,v[i]*1.0/n[i];}' fruits.txt
    Re ! Du coup pour cette partie, si une moyenne c'est la somme de chaque terme, divisée le nombre de termes, du coup là ce serait

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    v[i]*1.0 # la somme de chaque terme
    n[i]; # la somme du nombre de termes
    que signifie cela ?

  6. #6
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 288
    Par défaut
    Valeur du tableau v pour la clé i, multiplié par 1.

  7. #7
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 349
    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 349
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Petit détail, on est en nombre flottant, les calculs offerts par le shell ne marcheront pas (int). On peut passer par "bc". Exemple echo "1/3" |bc -l.
    En fait, il existe une astuce en BASH:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ printf %.10f\\n "$((10**9 * (8 + 6 + 6 + 12 +7) / 5))e-9"
    7.8000000000
    $ printf %.10f\\n "$((10**9 * (4 + 6 + 6 + 3) / 4))e-9"
    4.7500000000

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Flodelarab Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ awk '/#|^ *$/{next;} {v[$1]+=$2;n[$1]++;} END{for (i in n) print i,v[i]*1.0/n[i];}' fruits.txt 
    1 7.8
    2 4.75
    Tu sais à quoi ça me fait penser ce /#|^ *$/? A moi quand j'ai ramené l'énoncé de maths de mon concours à ma mère qui m'a dit "j'arrive même pas à comprendre la question"
    Je sens que ça doit avoir vaguement un rapport avec le "#" en première ligne du fichier mais ensuite...

    Citation Envoyé par disedorgue Voir le message
    En fait, il existe une astuce...
    Joli (plus je viens ici plus je vois à quel point je suis à la rue en bash...). Bon, c'est pas grave, tant que j'arrive à coder mes propres solutions, tant pis si je passe par bc...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 288
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Je sens que ça doit avoir vaguement un rapport avec le "#" en première ligne du fichier mais ensuite...
    Il y a une difficulté supplémentaire. Dans les regex, il faut savoir si les caractères sont interprétés ou considérés pour eux-mêmes. Et cette interprétation change en fonction des contextes. En sed, on aurait dit /#\|^ *$/.
    Cette regex désigne une chaîne de caractère avec un croisillon ou une ligne composée exclusivement d'espaces en quantité indéterminée. Elle permet de nettoyer le fichier des lignes sans objet.
    # -> un croisillon
    | -> ou
    ^ -> début de ligne
    * -> objet précédent en quantité 0 ou plus.
    $ -> fin de ligne

    Le reste, c'est de l'anglais.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 658
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    En fait, il existe une astuce en BASH:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ printf %.10f\\n "$((10**9 * (8 + 6 + 6 + 12 +7) / 5))e-9"
    7.8000000000
    $ printf %.10f\\n "$((10**9 * (4 + 6 + 6 + 3) / 4))e-9"
    4.7500000000
    oui, ça donne un résultat décimal, mais ça ne calcule quand même pas des décimaux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ printf %.10f\\n "$((10**9 * (8 + 6 + 6.2 + 12 +7) / 5))e-9"
    bash: 10**9 * (8 + 6 + 6.2 + 12 +7) / 5 : erreur de syntaxe : opérateur arithmétique non valable (le symbole erroné est «*.2 + 12 +7) / 5*»)
    et, attention si vous comptez modifier le séparateur décimal en ,, l'évaluation arithmétique considérera qu'il y deux calculs : 8+6+6 et 2+12+7.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 349
    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 349
    Par défaut
    C'est juste un détail:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ printf -v XX '%.2f%s' 8 + 6 + 6.2 + 12 + 7
    $ printf -v YY '%.2f%s' 5
    $ printf %.10f\\n "$((10**9 * (${XX//./})/${YY//./}))e-9"
    7.8400000000

  12. #12
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 288
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ printf -v XX '%.2f%s' 8 + 6 + 6.2 + 12 + 7
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ printf -v XX '%.2f%s' 8 + 6 + 6.2 + 12 + 7
    -bash: printf: 6.2: nombre non valable
    Perdu

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ printf -v XX '%.2f%s' 8 + 6 + 6.2 + 12 + 7
    -bash: printf: 6.2: nombre non valable
    $ printf -v XX '%.2f%s' 8 + 6 + 6,2 + 12 + 7
    $

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

Discussions similaires

  1. Extraire un argument parmis plusieurs en bash
    Par syl1405 dans le forum Linux
    Réponses: 13
    Dernier message: 20/07/2010, 12h28
  2. Extraire le dernier mot d'une chaîne en bash
    Par oranoutan dans le forum Linux
    Réponses: 2
    Dernier message: 16/05/2010, 22h47
  3. [BASH] extraire une chaine d'une autre
    Par zevince dans le forum Linux
    Réponses: 4
    Dernier message: 05/03/2009, 12h00
  4. Réponses: 1
    Dernier message: 11/01/2009, 11h34
  5. Extraire des lignes d'un fichier en commande bash
    Par newnew dans le forum Linux
    Réponses: 3
    Dernier message: 27/07/2004, 16h22

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