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 :

Commande bc avec option l


Sujet :

Shell et commandes GNU

  1. #1
    Invité
    Invité(e)
    Par défaut Commande bc avec option l
    Salut le forum,
    J'analyse un bout code et une partie de ce code me pose problème.
    Il s'agit d'une condition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (($(echo "$1">"$2" | bc -l) ))
    Pour l'instant je ne peux pas executer le code.
    Mais:
    1) je ne comprends pas la syntaxe $(echo......)
    2) bc est la commande de calculatrice? l'option l est pour l'arrondi, mais on est d'accord que c'est totalement inutile ici car on ne calcule rien, on fait juste de la comparaison

    Merci

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

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

    Aïe. Ouille. Reprécisons.

    • (( )) est une évaluation arithmétique. Pas une condition. Une condition serait plutôt [ ] ou [[ ]]. Avec leurs propres règles. help test pour plus d'infos.
    • echo "$1">"$2" est une redirection. Elle veut dire "écrire le contenu de la variable 1 dans un fichier dont le nom est dans la variable 2. Si $1 contient 1 et $2 contient 2, tu obtiens un fichier appelé 2 qui contient la valeur 1.
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      $ echo "1">"2"
      $ ls -l 2
      -rw-r--r-- 1 flo flo 2 sept. 11 01:33 2
      $ cat 2
      1
    • $( ) est une substitution de commande. Elle fait comme si le résultat d'une commande (un fichier texte) était une chaîne de caractère. man bash pour plus d'infos.
    • "on fait juste de la comparaison". Tu as maintenant compris qu'il n'y a pas la moindre comparaison dans ce qui est tapé dans ton message initial.


    Cela te fait pas mal de lecture avant d'aller plus loin.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    oulala d'accord je découvre un peu le bash et je me suis fait piégé en faisant des raccourcis avec d'autres langages.
    Après je me demande si la personne qui a fait le script ne sait pas mélangé aussi car:
    j'ai un premier fichier qui contient des données grafana: moyenne et seuil de machines
    La moyenne représente toutes les données sur une période donnée
    et le seuil est une valeur pour lequel on détermine qu'il y a un soucis.

    APrès cette première vérif on regarde si les valeurs (donc une par une sans moyenne) sont supérieur ou non au seuil et en fonction je note d'un un fichier:

    Moyenne > seuil mais valeurs < seuil
    Moyenne < seuil mais valeurs < seuil
    Moyenne > seuil mais valeurs < seuil
    .....

    mais ça me parait vraiment bizarre avec des
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if (( $(echo $xx>$yy| bc)
        if ( $(echo $aa>$yy| bc)
    Je ferais plus un truc comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if [  $xx>$yy)
        if [  $aa>$yy ]
    et sans bc ....
    Mais le truc c'est que ça marchait avant, marchait dans le sens où dans le fichier j'avais bien des alertes style: Moyenne > seuil mais valeurs < seuil

    Donc, je suis un peu perdu. Je sais pas si je comprends mal et que mon idée de juste comparer les valeurs est fausse ou si c'est l'idée principale qui n'est pas bonne

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    Par défaut
    STOOOP ! Quel est ton interpréteur de commande ? Pour le savoir, 2 choses à faire :

    Ce serait pas csh, plutôt que bash ? ou un autre interpréteur atypique ?


    Le problème, c'est que bash ne comprend que les nombres entiers. Dès que tu vas vouloir utiliser des nombres à virgule, il faut aller voir ailleurs (bc, awk, etc).
    Entre parenthèses, le ">" de ce code est une comparaison dans l'ordre lexicographique. Pas l'ordre numérique. 10 est devant 9 dans l'ordre lexicographique, mais 10 derrière 9 dans l'ordre numérique.

    Spontanément, je prendrais awk pour faire ce travail. Ton fichier est organisé en lignes et colonnes ?

  5. #5
    Invité
    Invité(e)
    Par défaut
    Salut,
    Il s'agit bien du bash.

    donc en fait ce qu'a fait la personne en créant le script n'est peut-être pas si faux.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (( $(echo $xx>$yy| bc)
        if ( $(echo $aa>$yy| bc)
    Le bc va permettre de gérer les nombres à virgules ce qui est mon cas ici.

    Après j'avoue que je ne comprends pas bien pourquoi il a utilisé la substitution de commande.

    Ce que je pensais faire c'est juste comparer la valeur x avec y (eventuelement avec bc pour gerer les nombres a virgules) pour determiner si la moyenne est < ou > au seuil.
    Puis après je détermine si la valeur est < ou > au seuil (toujours avec bc)

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    Par défaut
    À chaque message, tu changes les parenthèses ouvrantes, fermantes, crochets. On ne peut pas suivre. Quel est le vrai code ?
    • ( ) est un sous-shell
    • (( )) est une évaluation arithmétique
    • [ ] est un test simple. C'est un raccourci de la commande test.
    • [[ ]] est un test étendu.
    • { ;} est un regroupement de commande, sans sous-shell.
    • $( ) est une substitution de commande.
    • $(( )) est une évaluation arithmétique qui renvoie le résultat.

    Il ne faut pas confondre le code retour et les canaux de communication. Un logiciel écrit sur la sortie standard, écrit sur la sortie d'erreur, et envoie un code retour. Ce sont 3 choses différentes.



    Reconstruis dans l'ordre pour bien comprendre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ echo "2.10>2.9"
    2.10>2.9
    $ echo "2.10>2.9" | bc -l
    0
    $ res=$(echo "2.10>2.9" | bc -l)
    $ if (( $res )); then echo OK; else echo ko;fi
    ko
    $ res=$(echo "2.10<2.9" | bc -l)
    $ if (( $res )); then echo OK; else echo ko;fi
    OK
    Note que le ">" est DANS les double quotes.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Salut,

    Je vais regarder en détail ton message.

    Voilà le code initial

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    cat fichier1.json |sed 1d |while a b c d e f 
     
    cat fichier2.json |while read y z
    do
     if (( $(echo "$c > $f" |bc -l) ))
    then
        if (( $(echo "$z < $f" |bc -l) )) 
        then
        echo "moyenne haute mais valeur basse"
    Pour moi ça ne reste pas logique de faire comme ça je trouve plus logique de faire des comparaison

  8. #8
    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
    c'est du très mauvais code, mais les conditions sont correctes, parce que la Substitution de commande sur bc affiche le résultat de la comparaison, dont l'évaluation arithmétique sera utilisée par if.

    • le JSON se traite avec un processeur JSON, tel que jq
    • UUOC
    • sed inutile
    • noms de variables non évocateurs de leur contenu.
    • ... on n'a pas tout


    NB : l'option -l n'a pas d'utilité ici.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Salut N_BaH,
    merci de participer à la discussion.
    Alors je comprends que les conditions mise en place permettent donc de faire la comparaison.

    Le sed dans le cat permet d'eliminer la première ligne qui est une légende, par exemple: nom de la machine, valeur, ....
    Je n'ai pas trouvé comment supprimé cette ligne avec jq

    Quesque l'UUOC?

    Le nom des variables c'est quelques choses que je vais changer car effectivement ce n'est pas parlant

    La suite du code c'est quasi pareil avec les conditions dans l'autre sens.

    Comment pourrais-je modifier ce code en vrai code?

  10. #10
    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
    le sed n'est pas utile, on peut très bien faire une condition dans la boucle de lecture pour ne traiter que les lignes > 1

    UUOC : Useless Use Of Cat

    ce n'est pas une ligne que peut remplacer jq, c'est tout le script, s'il ne fait que traiter le JSON.

    à mon avis, tu prends ce script, et tu le mets aux toilettes. Rustiner un script mal foutu, c'est pire que tout.
    tu nous montres les fichiers (vu le traitement, je ne suis même pas sûr que ce soit du JSON), tu nous expliques ce qu'il faut en faire, et, nous, on t'explique comment faire proprement.
    déjà, selon le format des fichiers, on peut certainement les joindre pour éviter l'imbrication de boucle.
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Invité
    Invité(e)
    Par défaut
    J'ai adapté le code pour qu'on se comprenne mieux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    cat reference.json |sed 1d |while serveurs moyenne limite //Dans ce fichier qui contient la première ligne en légende on a des valeurs de références sur une période passée
     
    cat actuel.json |while read valeur  //Dans ce fichier on recupére les valeurs actuel de nos serveurs
    do
     if (( $(echo "$moyenne> $seuil" |bc -l) ))
    then
        if (( $(echo "$valeur < $seuil" |bc -l) )) 
        then
        echo "moyenne haute mais valeur basse"
    le fichier reference est plutot un fichier texte contenant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    serveurs moyenne limite
    win1  99.7196 95.7196
    Le second fichier j'ai des valeurs comme:
    98.58
    96.02
    etc...

    Donc au final je pense qu'il faut déjà modifier l'extension des fichier qui ne ressemble pas à du json....
    EN fait au départ les fichiers sont en json puis un traitement est fait avec jq et le resultat est stocké dans un fichier references.json mais est-ce qu'on peut dire que c'est encore du json?
    Dernière modification par Invité ; 11/09/2021 à 16h39.

  12. #12
    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
    pas de champs commun, donc pas de join.
    par contre, si le nombre de lignes est le même (ce qui serait logique), on peut faire un paste sur ces fichiers afin de n'avoir qu'une seule boucle while :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while read srv moyN seuil val
    do
       : if ((...
    done < <(paste <(sed 1d fichier1) fichier2)
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  13. #13
    Invité
    Invité(e)
    Par défaut
    en fait non les fichiers n'ont pas le meme nombre de ligne.
    Dans le premier fichier: reference.json
    on a pour chaque machine une moyenne est un seuil
    dans le second fichier: actuel.json
    Il y a plusieurs valeurs (pour une machine) correspondant aux différentes valeurs remontées sur 1 h (a l'inverse que le premier fichier on ne fait pas la moyenne).

  14. #14
    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
    lignes ou colonnes ?
    il y a autant de machines dans le "fichier des références" (moyenne/seuil) que dans le "fichier des valeurs", non ? une ligne par machine dans les deux fichiers ?

    tu peux nous joindre ces deux fichiers ?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  15. #15
    Invité
    Invité(e)
    Par défaut
    Dans le premier fichier il y a une ligne par machine avec 3 colonne (machine moyenne et limite)

    Dans le second fichier, il y a plusieurs lignes correspondant à la même machine.

  16. #16
    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
    alors, les deux fichiers ont donc bien au moins un champ en commun : le nom de la machine ?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  17. #17
    Invité
    Invité(e)
    Par défaut
    Non même pas

    car le second fichier récupère les valeurs pour une machine. On stocke donc les valeurs dans le fichier, et on fait le comparaison on supprime le fichier et on passe a une autre machine

  18. #18
    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
    d'aaaccord.

    avec une bocule while, je mettrais le "fichier référence" dans un tableau associatif machines, avec comme indice le nom des machines, et comme valeurs, la moyenne et le seuil.
    ensuite, je boucle avec for ...in...; do ...; done sur les indices du tableau pour récupérer le fichier correspondant, et je compare les données (la "découpe" des valeurs du tableau associatif est trivial).
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

Discussions similaires

  1. Réponses: 4
    Dernier message: 09/10/2020, 09h38
  2. commande qui copie fichier avec options
    Par pandora19 dans le forum C
    Réponses: 2
    Dernier message: 03/11/2012, 16h33
  3. Réponses: 4
    Dernier message: 07/06/2012, 16h18
  4. [MCD] Commande de produit avec option
    Par Lei57 dans le forum Schéma
    Réponses: 12
    Dernier message: 07/06/2012, 01h47
  5. Réponses: 3
    Dernier message: 10/09/2009, 11h08

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