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

  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 815
    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 815
    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 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 287
    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
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 342
    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 342
    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

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 815
    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 815
    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]

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 640
    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.

  8. #8
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 342
    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 342
    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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 287
    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
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 287
    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
    $

  11. #11
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 342
    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 342
    Par défaut
    Soit ton bash ne supporte pas, soit tu es en virgule et non en point pour les floats.

  12. #12
    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
    Merci pour toutes votre aide !

    Je décortique encore le script awk x)

    Comme extraire la ligne qui a la valeur la plus proche de la moyenne ?

    Si j'obtiens une moyenne de 7.94, comment dire au bash de "print" Orange ?

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 640
    Par défaut
    pareil que Flodelarab avec GNU bash, version 5.1.4(1)-release (x86_64-pc-linux-gnu)
    et pareil avec GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu).

    EDIT : OK, il faut mettre une virgule !
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  14. #14
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 342
    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 342
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    pareil que Flodelarab avec GNU bash, version 5.1.4(1)-release (x86_64-pc-linux-gnu)
    et pareil avec GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu).
    Tu as fait un update de ton bash juste pour vérifier ?

  15. #15
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 342
    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 342
    Par défaut
    Citation Envoyé par Dorhub Voir le message
    Merci pour toutes votre aide !

    Je décortique encore le script awk x)

    Comme extraire la ligne qui a la valeur la plus proche de la moyenne ?

    Si j'obtiens une moyenne de 7.94, comment dire au bash de "print" Orange ?
    Et comment tu ferais , toi (au moins algorithmiquement parlant) ?

    Car là, on est un peu dans le vague sur le format de tes nombres (est-ce des entiers, et sinon combien de chiffre après la virgule, et si on a 2 possibilités, lequel on prend (le plus grand ou le plus petit) et si égaux) ?

    PS: A la communauté, un petit script builtin bash ?

  16. #16
    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
    Moi je ferais une comparaison de la difference de chaque valeur avec la moyenne, puis un echo de la ligne de la valeur la plus proche

  17. #17
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 815
    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 815
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Dorhub Voir le message
    Citation Envoyé par Sve@r Voir le message
    puis le reste ce n'est que de la lecture et soustraction et comparaison du résultat...
    Moi je ferais une comparaison de la difference de chaque valeur avec la moyenne, puis un echo de la ligne de la valeur la plus proche
    Ben voilà. Exactement comme déjà dit précédemment. Ne reste plus qu'à...
    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]

  18. #18
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 342
    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 342
    Par défaut
    Ouais, pas de bras, pas de chocolat...

    moyenne=5

    orange=4
    prune=4
    citron=6

    On choisit quoi ????

    Dans ton fichier, est-ce que tu as des valeurs du type 4,9123456789332134448607784378294958432923448586976543922 ?

    Merci de faire un peu d'effort...

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 287
    Par défaut
    Si c'est pour une épreuve de CodingGame, il me semble que la réponse est la médiane. Pas la moyenne.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 640
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Tu as fait un update de ton bash juste pour vérifier ?
    non, j'ai des machines avec des OS Linux différents.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 5 12345 DernièreDernière

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