Langage perl

ba_na Messages postés 1 Statut Membre -  
na_ba85 Messages postés 8 Statut Membre -
bonjour,

Je suis debutante en Perl et jaurai besoin d'aide pour resoudre un script.

Merci d'avance

cordialement,
naba

2 réponses

  1. [Dal] Messages postés 6122 Date d'inscription   Statut Contributeur Dernière intervention   1 108
     
    Salut naba,

    De quel type d'aide as-tu besoin ? Tes indications sont un peu courtes :-)

    Dal
    0
  2. na_ba85 Messages postés 8 Statut Membre
     
    Bonjour Dal,

    Tout d'abord merci pour ta reponse et conseil.

    Voici mon script avec les infos où je bloque :

    # But : De chercher les mots suivants (mot1, mot2, mot3, mot4) dans le fichier.txt.
    # A chaque mot trouvé, ça me renvoi Ok et passe au suivant et ainsi de siute
    # Si un mot n'est pas present, il me renvoi KO
    # Déclarations de mes variables

    my $fic_log_uc = "......./fichier.txt";
    my ($valeur1,$mot1);
    my ($valeur2,$mot2);
    my $status = 'KO';

    # Main

    open (LIRE_LOG, '<', $fic_log) or die "Impossible d'acceder au fichier";

    while (<LIRE_LOG>)
    {
    # Appel de ma fonction
    main->check;

    }

    print LOG "$mot1;$mot2;$status\n";
    close (LOG);
    close (LIRE_LOG);

    # Functions

    sub check
    {
    if ($_ =~ /mot1/)
    {
    #print "$_\n";
    ($valeur1,$mot1) = split(/=/,$_);
    $mot1=~ s/\r//;
    chomp($mot1);
    $status = "OK";
    }

    if ($_ =~ /mot2/)
    {
    #print "$_\n";
    ($valeur2,$mot2) = split(/=/,$_);
    $mot2=~ s/\r//;
    chomp($mot2);
    $status = "OK";
    }

    if ($_ =~ /mot3/)
    {
    #print "$_\n";
    $status = "OK";
    }

    if ($_ =~ /mot4/)
    {
    #print "$_\n";
    $status = "OK";
    }

    elsif ($status eq "KO")
    {
    $mot1 = "inexistant";
    $mot2 = "inexistant";
    $status = "KO";
    #print "$status\n";
    }

    return $mot1;
    return $mot2;
    return $status;
    }

    # Mon script ne marche pas car le mot4 n'est pas present dans mon fichier, il me renvoi comme même OK :(

    Merci pour votre aide
    0
    1. [Dal] Messages postés 6122 Date d'inscription   Statut Contributeur Dernière intervention   1 108
       
      OK, peux-tu donner un exemple de fichier.txt correspondant à ce code ?


      Dal
      0
    2. na_ba85 Messages postés 8 Statut Membre
       
      oui voici un exemple général :

      =======================================================
      Fichier.txt
      =======================================================

      |-- ..............................
      |-- mot1 = XXXXX # j'ai extrait cette valeur
      |-- mot2 = XXXXX # j'ai extrait cette valeur

      mot3 !!!
      mot4 !! # lors de la verification d'un des fichiers, ce mot n'est pas present

      => Mon script doit lire le fichier et à chaque fois qu'il trouve un mot il passe au suivant ....
      Si les 4 sont bien presents alors il me renvoi OK et si il en manque au moins un il me renvoi KO et arrete de lire mon fichier
      0
    3. [Dal] Messages postés 6122 Date d'inscription   Statut Contributeur Dernière intervention   1 108
       
      Bon, alors, je vais considérer que ce qui t'intéresse dans ton fichier, ce sont des lignes contenant :

      mot1 = XXXXX
      mot2 = YYYYY
      mot3 = ZZZZZ

      C'est à dire des lignes commençant par mot1, mot2, mot3 et mot4 sans rien avant et sans rien après les valeurs "XXXXX" (il y a des "|-- " dans ton exemple avant le mot et des commentaires après).

      D'autre part, je comprends que tu veux récupérer la valeur "XXXXX", etc., et mettre cela dans $valeur1, etc.

      Le code suivant :

      #!/usr/bin/perl
      
      use strict;
      use warnings;
      
      my $fic_log_uc = "fichier.txt";
      my ($valeur1, $valeur2, $valeur3, $valeur4);
      my ($mot1, $mot2, $mot3, $mot4);
      my $status = 'KO';
      
      $mot1 = $mot2 = $mot3 = $mot4 = "inexistant";
      $valeur1 = $valeur2 = $valeur3 = $valeur4 = "";
      
      open (LIRE_LOG, '<', $fic_log_uc) or die "Impossible d'acceder au fichier";
      while (<LIRE_LOG>)
      {
          check();
      }
      close (LIRE_LOG);
      
      if ( ($mot1 eq "inexistant") || ($mot2 eq "inexistant") || ($mot3 eq "inexistant") || ($mot4 eq "inexistant") )
      {
          $status = "KO";
      } else
      {
          $status = "OK";
      }
      
      # do something with the acquired results
      print "$mot1;$valeur1;$mot2;$valeur2;$mot3;$valeur3;$mot4;$valeur4;$status\n";
      exit;
      
      sub check
      {
          if ($_ =~ /^mot1\s*=\s*([^\s]+)\s*$/)
          {
              $mot1 = "mot1";
              $valeur1 = $1;
          }
          if ($_ =~ /^mot2\s*=\s*([^\s]+)\s*$/)
          {
              $mot2 = "mot2";
              $valeur2 = $1;
          }
          if ($_ =~ /^mot3\s*=\s*([^\s]+)\s*$/)
          {
              $mot3 = "mot3";
              $valeur3 = $1;
          }
          if ($_ =~ /^mot4\s*=\s*([^\s]+)\s*$/)
          {
              $mot4 = "mot4";
              $valeur4 = $1;
          }
      }

      renvoie :

      mot1;XXXXX;mot2;YYYYY;mot3;ZZZZZ;inexistant;;KO

      pour un fichier contenant :

      mot1 = XXXXX
      mot2 = YYYYY
      mot3 = ZZZZZ

      et :

      mot1;XXXXX;mot2;YYYYY;mot3;ZZZZZ;mot4;12345;OK

      pour un fichier contenant :

      mot1 = XXXXX
      mot2 = YYYYY
      mot3 = ZZZZZ
      mot4 = 12345

      Ce sont des exemples, car ne ne comprend pas bien ton code, qui visiblement est partiel, écrit des choses dans un fichier qui devrait être ouvert et qui ne l'est pas dans ce que tu adresses, etc., et le format de présentation des résultats n'est pas compréhensible pour moi.

      Dans la mesure où tu utilises des variables globales, je ne vois pas ce que tu dois retourner avec "return" à la fin de la fonction Perl. Une chose est sûre, Perl s'arrêtera au premier "return".

      Dans mon exemple ci-dessus, j'ai fait sans.

      J'ai aussi utilisé une regexp avec capture, plutôt que faire une regexp puis un split (ce qui est à la fois plus robuste, rapide et plus concis).

      Il y a du code dupliqué dans la fonction (que j'ai laissé pour coller à ton code, qui est déjà bien modifié). Dans un code plus refactorisé, on mettrait les mots et valeurs dans des tableaux, et on aurait un seul if dans la fonction (dans une boucle for, par exemple).

      Une des principales erreurs dans ton code est qu'alors que tu utilises la fonction pour chaque ligne du fichier, tu en tires des conclusions en fin de chaque itération comme si tu avais analysé toutes les lignes. Ce n'est pas le cas. Le résultat final de l'analyse ligne par ligne ne peut se faire qu'en dehors de la boucle principale while (<LIRE_LOG>).


      Dal
      0
    4. na_ba85 Messages postés 8 Statut Membre
       
      Bonjour Dal,

      Je vous remercie enormement et grâce à vous j'ai compris mon erreur. En fait pour moi, il analyse que la ligne où je lui demande de chercher un mot particulier. Mais le fait que vous m'avez dit qu'il analyse ligne par ligne alors c'est normal qu'il me renvoi systematiquement OK car la dernier ligne comprend un de mes mots :(

      j'ai essayé de comprende votre expression regulier :
      /^mot1\s*=\s*([^\s]+)\s*$/

      Celui-ci \s*([^\s]+)\s*$/ correspond à ma valeur.
      Vous pouvez la signification \s car sur internet, ca signifie un separateur.

      Encore merci :D
      0
    5. [Dal] Messages postés 6122 Date d'inscription   Statut Contributeur Dernière intervention   1 108
       
      \s signifie un caractère "blanc", c'est à dire un espace ou une tabulation.

      ce qui est capturé (ta "valeur") est ce qui est représenté entre parenthèses : ([^\s]+) signifie capture un ou plusieurs caractères qui se suivent et qui sont non "blancs" (les crochets servent à définir une liste de caractères acceptables, les faire précéder d'un ^ constitue une négation, le + signifie 1 ou plus de ces caractères ainsi définis).

      les autres \s sont destinés à permettre d'ignorer les éventuels espaces, ou "blancs" qui figureraient de part et d'autre de la valeur (ainsi qu'à la suite du mot1 et à gauche du signe =).

      Voilà le détail de l'explication de :

      /^mot1\s*=\s*([^\s]+)\s*$/

      - à partir du début de ligne
      - matche mot1
      - suivit de zéro ou plusieurs "blancs" à la suite (espaces ou tabulations)
      - suivis de =
      - suivit de zéro ou plusieurs "blancs" à la suite
      - on capture ensuite un ou plusieurs caractères à la suite qui ne sont pas des blancs
      - ils peuvent être suivis de zéro ou plusieurs "blancs" à la suite jusqu'à la fin de la ligne

      https://www.commentcamarche.net/contents/803-php-expressions-regulieres


      Dal
      0