Perl & commande grep

Résolu
Bonjour,

je suis entrain de developper un script perl, qui me permet de filtrer les résultats d'une commande en utilisant grep (JMX | grep ?????) sous linux de la maniére suivante:

celle qui ont size = 0 affichage du message "OK"
celle qui ont size <10 affichage du message "Status = Critical / Destination = ERP.FR && Size = 1"
celle qui ont size <10 affichage du message "Status = Warning / Destination = ERP.HU && Size = 10"

les résultats ont la forme suivante :

Destination = ERP.DE
Type = Queue
Size = 0

Destination = ERP.FR
Type = Queue
Size = 1

Destination = ERP.CN
Type = Queue
Size = 0

Destination = ERP.HU
Type = Queue
Size = 10


Merci de m'aider a accomplir cette tache,

Merci d avance

titexe
Configuration: Windows XP Internet Explorer 7.0

7 réponses

  1. Salut,

    Si j'ai bien compris ce que tu veux, vite fait, deux possibilités

    Le fichier

    lami20j@debian:~$ cat titexe2009
    Destination = ERP.DE
    Type = Queue
    Size = 0

    Destination = ERP.FR
    Type = Queue
    Size = 5

    Destination = ERP.CN
    Type = Queue
    Size = 3

    Destination = ERP.HU
    Type = Queue
    Size = 10

    Destination = ERP.SP
    Type = Queue
    Size = 20

    Destination = ERP.GB
    Type = Queue
    Size = 1

    Destination = ERP.CZ
    Type = Queue
    Size = 17

    Destination = ERP.BE
    Type = Queue
    Size = 150

    Version 1
    Le script<souligne>

    lami20j@debian:~$# cat size.pl
    !#/usr/bin/perl
    use strict;use warnings;
    
    while(<DATA>){
      if (/Destination\s*=\s*(.*)/ .. /^$/){
        my $dest=$1;
        if (/Size\s*=\s*(\d+)/){
          $1==0
              ? print   "Status = OK       / Destination = $dest && Size = 0\n"
              : $1<10
                ? print "Status = Critical / Destination = $dest && Size = $1\n"
                : print "Status = Warning  / Destination = $dest && Size = $1\n";
        }
      }
    }
    


    <souligne>L'exécution


    lami20j@debian:~$ perl size.pl
    Status = OK       / Destination = ERP.DE && Size = 0
    Status = Critical / Destination = ERP.FR && Size = 5
    Status = Critical / Destination = ERP.CN && Size = 3
    Status = Warning  / Destination = ERP.HU && Size = 10
    Status = Warning  / Destination = ERP.SP && Size = 20
    Status = Critical / Destination = ERP.GB && Size = 1
    Status = Warning  / Destination = ERP.CZ && Size = 17
    Status = Warning  / Destination = ERP.BE && Size = 150
    


    Version 2
    Le script<souligne>

    lami20j@debian:~$ cat size2.pl
    #!/usr/bin/perl
    use strict;use warnings;
    use v5.10;
    
    while(<DATA>){
      if (/Destination\s*=\s*(.*)/ .. /^$/){
        my $dest=$1;
        if (/Size\s*=\s*(\d+)/){
          given ($1){
            when($1==0){say "Status = OK       / Destination = $dest && Size = 0" ;}
            when($1<10){say "Status = Critical / Destination = $dest && Size = $1";}
            default    {say "Status = Warning  / Destination = $dest && Size = $1";}
          }
        }
      }
    }
    


    <souligne>L'exécution


    lami20j@debian:~$ perl size2.pl
    Status = OK       / Destination = ERP.DE && Size = 0
    Status = Critical / Destination = ERP.FR && Size = 5
    Status = Critical / Destination = ERP.CN && Size = 3
    Status = Warning  / Destination = ERP.HU && Size = 10
    Status = Warning  / Destination = ERP.SP && Size = 20
    Status = Critical / Destination = ERP.GB && Size = 1
    Status = Warning  / Destination = ERP.CZ && Size = 17
    Status = Warning  / Destination = ERP.BE && Size = 150
    
    1. Bonjour,

      Merci pour votre réponse,

      j'ai essayé de mettre en place votre solution, mais l'expression While(<DATA>) n'est pas reconnue, je recois toujours une erreur au niveau de cette ligne :

      JMXURL=service:jmx:rmi:///jndi/rmi://10.33.208.39:1099/jmxrmi
      Queue=*
      JAR=/usr/run.jar
      FILE=/usr/titexe2009

      CMD_TMPL="java -jar $JAR query -QQueue=$Queue --jmxurl $JMXURL"
      WORKING=`$CMD_TMPL 2>&1`
      echo "$WORKING" > $FILE

      use strict;
      use warnings;

      cat $FILE

      while(<DATA>){
      if (/Destination\s*=\s*(.*)/ .. /^$/){
      my $dest=$1;
      if (/Size\s*=\s*(\d+)/){
      given ($1){
      when($1==0){say "Status = OK / Destination = $dest && Size = 0" ;}
      when($1<10){say "Status = Critical / Destination = $dest && Size = $1";}
      default {say "Status = Warning / Destination = $dest && Size = $1";}
      }
      }
      }
      }

      Merci d'avance,

      Cordialement,

      titexe
  2. Salut,

    mais l'expression While(<DATA>) n'est pas reconnue,
    Désolé, mais j'ai fais un mauvais copier/coller

    En revanche fait attention. Ca ce n'est pas du perl

    JMXURL=service:jmx:rmi:///jndi/rmi://10.33.208.39:1099/jmxrmi
    Queue=*
    JAR=/usr/run.jar
    FILE=/usr/titexe2009

    CMD_TMPL="java -jar $JAR query -QQueue=$Queue --jmxurl $JMXURL"
    WORKING=`$CMD_TMPL 2>&1`
    echo "$WORKING" > $FILE


    Donc après avoir fait ce qui est en dessus avec un script shell, je suppose, tu obtiendras le fichier /usr/titexe2009

    Ensuite tu exécuteras un des deux scripts

    Script 1

    #!/usr/bin/perl
    use strict;use warnings;
    
    my $FILE='/usr/titexe2009';
    open F,"$FILE" or die "E/S : $FILE $!\n";
    
    while(<F>){
      if (/Destination\s*=\s*(.*)/ .. /^$/){
        my $dest=$1;
        if (/Size\s*=\s*(\d+)/){
          $1==0
              ? print   "Status = OK       / Destination = $dest && Size = 0\n"
              : $1<10
                ? print "Status = Critical / Destination = $dest && Size = $1\n"
                : print "Status = Warning  / Destination = $dest && Size = $1\n";
        }
      }
    }


    Script 2

    #!/usr/bin/perl
    use strict;use warnings;
    use v5.10;
    
    my $FILE='/usr/titexe2009';
    open F,"$FILE" or die "E/S : $FILE $!\n";
    
    while(<F>){
      if (/Destination\s*=\s*(.*)/ .. /^$/){
        my $dest=$1;
        if (/Size\s*=\s*(\d+)/){
          given ($1){
            when($1==0){say "Status = OK       / Destination = $dest && Size = 0" ;}
            when($1<10){say "Status = Critical / Destination = $dest && Size = $1";}
            default    {say "Status = Warning  / Destination = $dest && Size = $1";}
          }
        }
      }
    }
    1. Contributeur
      hello
      avec awk
      $ cat a2
      Destination = ERP.DE
      Type = Queue
      Size = 0
      
      Destination = ERP.FR
      Type = Queue
      Size = 1
      
      Destination = ERP.CN
      Type = Queue
      Size = 0
      
      Destination = ERP.HU
      Type = Queue
      Size = 11
      
      $ awk '/Destination/ {l=$0} ; /^Size/ {s=$3;stat="Warning";if(s<10)stat="Critical";if(s==0)stat="OK";printf("Status = %-8s / %s && %s\n", stat, l, $0)}' < a2
      Status = OK       / Destination = ERP.DE && Size = 0
      Status = Critical / Destination = ERP.FR && Size = 1
      Status = OK       / Destination = ERP.CN && Size = 0
      Status = Warning  / Destination = ERP.HU && Size = 11
      $ 
      1. Merci pour vos réponses,

        j'ai réussi avec vos aides de faire marcher le premier script perl.

        Sinon, j'ai réessayer de faire la même chose pour un autre cas, mais tellement je suis nul en perl, que je n'ai pas su comment le faire :

        si le champ TargetName existe dans le résultat --> affichage du message: "OK | TargetName = ERP.FR"
        sinon --> affichage du message "NOK | TargetName is Down"

        root$cat titexe2009

        Java Runtime: Sun Microsystems Inc. 1.6.0_0 /usr/lib/jvm/java-6-openjdk/jre
        Heap sizes: current=5056k free=4589k max=520256k
        JVM args:
        HOME: /usr/local/
        BASE: /usr/local/
        TargetName = ERP.FR

        Merci d'avance,

        Cordialement,

        titexe
        1. Salut,

          Sinon, j'ai réessayer de faire la même chose pour un autre cas, mais tellement je suis nul en perl,
          Si je peux me permettre. Il ne faut pas voir les choses ainsi.
          Je dirais plutôt que tu es débutant en Perl, mais ça ce n'est pas un problème. On a tous débuter un jour.

          que je n'ai pas su comment le faire :

          si le champ TargetName existe dans le résultat --> affichage du message: "OK | TargetName = ERP.FR"
          sinon --> affichage du message "NOK | TargetName is Down"


          En revanche il faut construire correctement l'algorithme suite à une analyse judicieuse de ta situation.

          Si le fichier a la structure que tu viens de la présenter, alors ton raisonnement est un peux faux.
          Si on a une ligne qui contient le champ TargetName (pour être plus précis je dirais des lignes qui commencent avec TargetName) alors le message peut être affiche sinon, on ne peux pas afficher Down pour un Target qui n'existe pas. Tu vois ce que je veux dire?

          Je vais te donner deux exemples pour me faire comprendre.

          1er cas - je vais utiliser ton fichier

          lami20j@debian:~$ cat target.txt
          Java Runtime: Sun Microsystems Inc. 1.6.0_0 /usr/lib/jvm/java-6-openjdk/jre
          Heap sizes: current=5056k free=4589k max=520256k
          JVM args:
          HOME: /usr/local/
          BASE: /usr/local/
          TargetName = ERP.FR
          lami20j@debian:~$
          lami20j@debian:~$ cat targetname.pl
          #!/usr/bin/perl
          use strict;use warnings;
          
          my $fic="/home/lami20j/target.txt";
          open F,"target.txt" or die "E/S : $fic $!\n";
          
          while(my $ligne=<F>){
            next unless $ligne=~/^TargetName/; # on saute les lignes qui
                                       # ne commencent pas
                                       # avec TargetName
            $ligne=~/=\s+(.*)/;
            print "OK | TargetName = $1\n";
          }
          __END__
          
          


          Le résultat
          lami20j@debian:~$ perl targetname.pl
          OK | TargetName = ERP.FR
          

          Mais ce n'est pas vraiment ça que tu veux.
          Tu veux avoir un message qui te dis si le TargetName est Down.

          En ce cas voici deux scénarios :

          - soit TargetName est vide et en ce cas on fait un test sur ce qui est après le signe égal
          - soit il y a quelque part un champ qui nous donne l'état du Target

          Dans les deux cas il n'y aura pas moyen de récupérer quelque chose qui n'existe pas, je parle de nom de target. Le champs TargetName doit exister quelque soit l'état (down ou pas)
          Si tu n'as pas besoin de nom, un message TargetName is Down, sans préciser le nom de target, n'est pas concluant vu que tu ne pourras pas savoir pour quel target tu auras le message.

          Pour simuler ton exercice voici un exemple
          (j'ai mis une structure de fichier adapté qui nous permettra de savoir l'étant du target)

          Le fichier modifié

          lami20j@debian:~$ cat target.txt
          Java Runtime: Sun Microsystems Inc. 1.6.0_0 /usr/lib/jvm/java-6-openjdk/jre
          Heap sizes: current=5056k free=4589k max=520256k
          JVM args:
          HOME: /usr/local/
          BASE: /usr/local/
          TargetName = ERP.FR;1
          
          
          Java Runtime: Sun Microsystems Inc. 1.6.0_0 /usr/lib/jvm/java-6-openjdk/jre
          Heap sizes: current=5056k free=4589k max=520256k
          JVM args:
          HOME: /usr/local/
          BASE: /usr/local/
          TargetName = ERP.UK;0


          Script + exécution

          lami20j@debian:~$ cat targetname2.pl
          #!/usr/bin/perl
          #use strict;use warnings;
          
          my $fic="/home/lami20j/target.txt";
          my($type,$target);
          open F,"target.txt" or die "E/S : $fic $!\n";
          
          while(<F>){
              next unless /^TargetName/;  # les lignes qui ne commencent pas
                                          # avec TargetName ne nous interessent pas
              /^Target.*=\s+(.*);(\d)/;
              $2==1 ?print "OK | TargetName = $1\n":print "NOK | $1 is DOWN\n";
          }
          __END__
          
          lami20j@debian:~$ perl targetname2.pl
          OK | TargetName = ERP.FR
          NOK | ERP.UK is DOWN


          Ce qu'on retiens dans cette histoire, c'est que pour trouver une solution adéquate, il fait savoir 3 choses
          - les données en entrée
          - le traitement qu'on veut appliquer aux données en entrée
          - un exemple concret de ce qu'on doit obtenir

          En ce moment on peut commencer chercher une solution.
          J'espère que je ne t'ai pas trop embrouillé.
          1. Merci pour ton soutien :)

            En fait je me suis mal exprimé , si le champ TargetName existe dans le fichier c'est "OK | TagetName = ERP.FR", Sinon le message est "NOK | TargetName is Down".

            Merci encore une fois.

            titexe
        2. Re,

          Pour être vraiment clair, ton fichier contiendra plusieurs Target ou il ne contiendra que ça ?


          Java Runtime: Sun Microsystems Inc. 1.6.0_0 /usr/lib/jvm/java-6-openjdk/jre
          Heap sizes: current=5056k free=4589k max=520256k
          JVM args:
          HOME: /usr/local/
          BASE: /usr/local/
          TargetName = ERP.FR
          1. mon fichier il va contenir soit ca :

            Java Runtime: Sun Microsystems Inc. 1.6.0_0 /usr/lib/jvm/java-6-openjdk/jre
            Heap sizes: current=5056k free=4589k max=520256k
            JVM args:
            HOME: /usr/local/
            BASE: /usr/local/
            TargetName = ERP.FR

            Soit ca :

            Java Runtime: Sun Microsystems Inc. 1.6.0_0 /usr/lib/jvm/java-6-openjdk/jre
            Heap sizes: current=5056k free=4589k max=520256k
            JVM args:
            HOME: /usr/local/
            BASE: /usr/local/
            Caused by: java.io.IOException: Failed to retrieve RMIServer stub: javax.naming.ConfigurationException [Root exception is java.rmi.UnknownHostException:

            c'est pour ca , le fait d'avoir TargetName, pour moi c'est un OK ;)
        3. Re,

          #!/usr/bin/perl
          use strict;use warnings;
          
          my $fic="/home/lami20j/target.txt";
          my $test=0;
          my $target='';
          open F,"target.txt" or die "E/S : $fic $!\n";
          
          while(<F>){
               /^TargetName.*=\s+(.*)/ and $target=$1 and $test=1;
          }
          $test?print "OK | TargetName = $target\n":print "NOK | TargetName is DOWN\n";
          __END__
          
          1. Merci beaucoup pour votre aide :)