Afficher le résultat de grep en 1 ligne
Répondre à la discussion
Affichage des résultats 1 à 7 sur 7

Afficher le résultat de grep en 1 ligne



  1. #1
    Carthman

    Afficher le résultat de grep en 1 ligne


    ------

    Bonjour à toutes et à tous,

    Je galère à trouver une solution à mon problème.

    J'utilise un module USB qui lit les trames de Teleinfo du Linky sur un Raspberry PI (ces trames sont mises à jour et envoyées en permanence par le Linky).
    Mais il y a seulement 4 informations qui me sont utiles : EAST, EAIT, SINSTS et SINSTI.

    J'ai trouvé un morceau de code qui me permet de trouver ces informations et de les envoyer au bon endroit :
    Code:
    #!/bin/bash
    DOMO_IP="192.168.X.X"       # Domoticz IP Address à renseigner
    DOMO_PORT="XXX"            # Domoticz Port à renseigner
    TELEINFO_CONSO_IDX="90"           # Teleinfo CONSO IDX à renseigner
    
    
    #EAST=$(grep EAST /dev/ttyUSB12 -m 1 | awk '{ print $2}')
    #EAIT=$(grep EAIT /dev/ttyUSB12 -m 1 | awk '{ print $2}')
    #SINSTS=$(grep SINSTS /dev/ttyUSB12 -m 1 | awk '{ print $2}')
    #SINSTI=$(grep SINSTI /dev/ttyUSB12 -m 1 | awk '{ print $2}')
    
    echo "EAST : $EAST"
    echo "EAIT : $EAIT"
    echo "SINSTS : $SINSTS"
    echo "SINSTI : $SINSTI"
    
    #if [[ $SINSTS = +([0-9]) ]] ; then
    #curl -s "Accept: application/json" "http://$DOMO_IP:$DOMO_PORT/json.htm?type=command&param=udevice&idx=$TELEINFO_CONSO_IDX&nvalue=0&svalue=$SINSTS;$EAST" > /dev/null
    #fi
    Ca fonctionne pas trop mal, mais ça peut être un peu lent, car même si j'ai mis l'ordre des différents grep en fonction de l'ordre d'arrivée des infos désirées, le temps de traitement peut sauter une trame et du coup ça attend la trame d'après pour récupérer l'info manquante.
    Je cherche donc à récupérer les 4 infos en une seule trame, avec cela :

    Code:
    grep -E 'EAST|EAIT|SINSTS|SINSTI' /dev/ttyUSB12 -m 4
    et j'obtient
    Code:
    SINSTS  03856   \
    SINSTI  00000   <
    EAST    026715032       )
    EAIT    002666950       '
    Le problème c'est que je n'arrive pas à utiliser ce résultat dans une variable : le $variable me renvoie que la première ligne :
    Code:
    TELEINFO=$(grep -E 'EAST|EAIT|SINSTS|SINSTI' /dev/ttyUSB12 -m 4)
    echo $TELEINFO
     SINSTI 00000 < '
    Bien sûr, en fonction de quand le script est déclenché, la première valeur à apparaitre n'est pas toujours la même !
    J'ai passer des heures à essayer différents moyens, avec sed, avec awk, avec | tr '\n' ' ',..., entre autres pour essayer de compiler le résultat affiché sur 4 lignes en une seule pour qu'elle puisse entrer dans la variable, rien n'y fait, je dois passer à côté de quelque chose, ou peut être faut-il définir la variable d'une autre manière ?

    Si quelqu'un est susceptible de m'aider, je suis preneur !!!

    Merci.

    -----

  2. #2
    raymolk

    Re : Afficher le résultat de grep en 1 ligne

    Pour récupérer les infos des quatre greps en une commande sur quatre lignes, tu peux faire :
    Code:
    awk '(/EAST/ && !a[0]){a[0]=$2} (/EAIT/ && !a[1]){a[1]=$2} (/SINSTS/ && !a[2]){a[2]=$2} (/SINSTI/ && !a[3]){a[3]=$2} END{for (i=0;i<4;i++) print a[i]}' /dev/ttyUSB12
    Ensuite, tu peux mettre ça dans un tableau bash comme ceci :
    Code:
    mapfile -t a < <(commande)
    où commande est à remplacer par la commande awk ci-dessus.

    Ensuite, tu accèdes au nième élément du tableau par "${a[n-1]}", par exemple :
    Code:
    if [[ ${a[2]} == +([0-9]) ]] ; then …
    Je n'ai pas testé tout ce que je dis là, c'est écrit à la volée : à toi de tester et débuguer éventuellement…

  3. #3
    Carthman

    Re : Afficher le résultat de grep en 1 ligne

    Merci pour ton retour.

    Alors entre temps j'ai trouvé une solution pour mon problème, et c'est également avec awk.
    Code:
    grep -E 'EAST|EAIT|SINSTS|SINSTI' /dev/ttyUSB12 -m 4 | awk '{ print($1 $2) }'
    Je me suis fait avoir car en testant cette commande dans le bash, ça me retourne ça
    Code:
    SINSTI00000
    EAST026717384
    EAIT002666950
    SINSTS00538
    Et je croyais à tord que ça allait être mal intégré dans la variable, comme c'était le cas au début de mon problème, mais en fait dans la script ça retourne ça :
    Code:
    EAST026717511 EAIT002666950 SINSTS00480 SINSTI00000
    Toutefois, je ne mets pas tout de suite en "Résolu", car je vais tester un peu ta solution !

  4. #4
    raymolk

    Re : Afficher le résultat de grep en 1 ligne

    Attention : faire un grep sur les quatre motifs avec -m 4 n'est en général pas équivalent à faire quatre greps sur chaque motif avec -m 1.
    La solution que j'ai donnée est presque équivalente aux quatre greps : la seule condition est que le second champ ne soit pas vide quand une ligne contenant un des quatre motifs recherchés existe (sinon la condition !a[n] dans awk restera vraie, et on continuera à accepter des lignes tant qu'on n'aura pas eu un second champ non vide).
    Mais si c'est vraiment nécessaire, cela peut être rendu équivalent.

  5. A voir en vidéo sur Futura
  6. #5
    raymolk

    Re : Afficher le résultat de grep en 1 ligne

    PS (plus possible d'éditer mon message…) : il faudrait aussi que le second champ soit différent de 0 en fait, ce qui pourrait éventuellement poser plus de problèmes…
    Il est peut-être donc préférable d'utiliser deux tableaux dans awk, en laissant aux éléments du second tableau jouer seuls le rôle de booléen :
    Code:
    awk '(/EAST/ && !b[0]){a[0]=$2; b[0]=1} (/EAIT/ && !b[1]){a[1]=$2; b[1]=1} (/SINSTS/ && !b[2]){a[2]=$2; b[2]=1} (/SINSTI/ && !b[3]){a[3]=$2; b[3]=1} END{for (i=0;i<4;i++) print a[i]}' /dev/ttyUSB12
    Avec ça, on doit être équivalent aux quatre greps.

  7. #6
    Carthman

    Re : Afficher le résultat de grep en 1 ligne

    Bonsoir,

    Merci pour ton implication.
    J'ai essayé ton code, mais comme ça il ne fonctionne pas, il faudrait que je fasse des essais.

    Mais j'ai réussi à faire ce que je voulais.
    La finalité c'était de récupérer les valeurs chiffrées des trames. Pas besoin de les stocker dans un tableau, elles sont envoyées dans une application json qui les stocke et les traite.
    J'ai juste besoin d'envoyer les valeurs chiffrées d'une trame, puis des autres en boucle derrière.

    Pour récupérer ce dont j'ai besoin, j'applique ce code :
    Code:
    grep -E 'EAST|EAIT|SINSTS|SINSTI' /dev/ttyUSB12 -m 4 | sort | awk '{ print($1 $2) }' | sed 's/[A-Z]//g'
    J'explique pour d'éventuelles personnes intéressées : le grep va chercher mes 4 infos sur le port USB, ensuite sort fait un classement alphabétique (plus facile à traiter), awk transforme les 4 lignes en une seule avec des espaces, et sed enlève le texte.

  8. #7
    raymolk

    Re : Afficher le résultat de grep en 1 ligne

    Si dans ton cas particulier le grep ramène ce qu'il faut, alors c'est pas forcément la peine de chercher l'équivalence.
    Tu aurais quand même pu mettre ce que fait sed dans awk, mais bon, le principal c'est que ça marche

Discussions similaires

  1. SQL: cherche aide d'afficher résultat entre 4 tables dans HTML table
    Par noam dans le forum Programmation et langages, Algorithmique
    Réponses: 21
    Dernier message: 31/03/2020, 08h52
  2. [Exercices] exo : faire un additionneur + décodeur + afficher le résultat
    Par cosmoff dans le forum Électronique
    Réponses: 16
    Dernier message: 08/05/2016, 13h59
  3. VBA_code pour rechercher valeur>afficher ligne
    Par ivgu1939 dans le forum Programmation et langages, Algorithmique
    Réponses: 5
    Dernier message: 08/08/2015, 11h37
  4. Afficher le résultat d'un calcul dans un formulaire web
    Par invite234d9cdb dans le forum Internet - Réseau - Sécurité générale
    Réponses: 1
    Dernier message: 20/08/2008, 11h38
  5. n'arrive plus à afficher vidéo TF1 en ligne
    Par Cornemuse dans le forum Internet - Réseau - Sécurité générale
    Réponses: 2
    Dernier message: 28/01/2005, 13h07