[perl] comparer une chaine de caractère de plusieurs lignes

comparer une chaine de caractère de plusieurs lignes [perl] - Perl - Programmation

Marsh Posté le 03-08-2006 à 17:37:31    

voila je cherche à savoir si toute une chaine de caractère qui tiens sur plusieurs lignes est presente ds un fichier de log sous linux
j'arrive pour l'instant a savoir si un mot est present ds un fichier mais pas une serie de ligne
 
exemple ds un fichier de log je voudrais savoir si le texte suivant est present :
CL313  V2.1.5   23-JAN-2002 06:15:23    0    30     5    4   7234 D <-- Default
CL314  V2.1.5   23-JAN-2002 06:15:46    0    30     5    4   7990 D
CL315  V2.1.5   23-JAN-2002 06:16:55    0    30     5    4  10212 D <-- Default
 

Code :
  1. #!/usr/bin/perl -w
  2. $lineno=0;
  3. $filename=$ARGV[0];
  4. $search=$ARGV[1];
  5. sub find_string {
  6. open(IN, $filename) || die ("open failed: $!\n" );
  7. while (<IN> ){
  8.  if (/$search/){
  9.  $lineno++;
  10.  printf "%3s ",$lineno;
  11.  print $_;
  12.  exit 0;
  13.  }
  14. }
  15. if($lineno==0){
  16.  print "pas de chaine\n";
  17.  exit 1;
  18. }
  19. }
  20. find_string();

Reply

Marsh Posté le 03-08-2006 à 17:37:31   

Reply

Marsh Posté le 03-08-2006 à 18:04:39    

arrête de lire ligne par ligne si tu cherches sur plusiers [:spamafote]
Donc lis tout ton fichier et fais la recherche dessus!

Reply

Marsh Posté le 04-08-2006 à 09:06:37    

comment faire aussi pour passer en parametre une recherche de plusieurs lignes ?

Reply

Marsh Posté le 04-08-2006 à 10:52:15    

Je modifie ta fonction find_string :
 

Code :
  1. sub find_string {
  2. open(IN, $filename) || die ("open failed: $!\n" );
  3.         # rajout ici
  4.         @_ = <IN>;               # @_ reçoit tout le fichier d'un coup
  5.         close(IN);
  6.         chomp(@_);              # on lui vire chaque "\n" en fin d'élément
  7.         $_ = join("", @_);       # $_ récupère une longue chaîne correspondant à TOUS les élements de @_
  8. if ($_ =~ /$search/){
  9.     $lineno++;
  10.     printf "%3s ",$lineno;
  11.     print $_;
  12.     exit 0;
  13. }
  14. if($lineno==0){
  15.     print "pas de chaine\n";
  16.     exit 1;
  17. }
  18. }
  19. find_string();


 
Je n'ai pas testé mon code mais il doit fonctionner.
 
Remarque : pourquoi fais-tu un exit 0 ou 1 dans ta fonction ? Tu pourrais faire un return plutôt et tester la valeur que te retourne la fonction ?


---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO -> Google Pixel 9 PRO XL
Reply

Marsh Posté le 04-08-2006 à 12:07:18    

les exit c en effet une erreur de ma part :)

Reply

Marsh Posté le 04-08-2006 à 12:10:41    

Aricoh, je pense qu'il y a un truc qui merde :o
Le compteur de ligne il est au far-west avec ton code!!!

Reply

Marsh Posté le 04-08-2006 à 12:13:13    

Le problème, c'est que ton compteur de ligne ne peut QUE merder à présent puisque $_ récupère toutes les lignes en une seule.
 
Mais vu que ce que tu cherches peut être éclaté sur plus d'une ligne, la recherche devient nettement plus chaud si tu dois conserver les lignes telles quelles.


Message édité par Aricoh le 04-08-2006 à 12:13:27

---------------
Samsung Galaxy S1 -> Samsung Galaxy S2 -> Samsung Note 2 -> Huawei Ascend Mate 7 -> ZTE Axon 7 -> OnePlus 6T -> Oppo Find X2 PRO -> Google Pixel 9 PRO XL
Reply

Marsh Posté le 04-08-2006 à 15:28:41    

le plus simple reste de lancer plusieurs fois le script en tester ligne par ligne finalement

Reply

Marsh Posté le 04-08-2006 à 16:18:21    

Tu splittes ton motif sur les retour à la ligne.
Tu testes uniquement si tu trouves une occurence de la 1ère ligne du motif dans ton fichier si oui tu testes les lignes suivantes si tout est bon tu récupères le numéro de la ligne qui matchait la 1ere ligne de ton motif.
 
Je sais pas si c'est clair, je crois que j'aurais mieux fait d'écrire le code!

Message cité 1 fois
Message édité par anapajari le 04-08-2006 à 16:18:43
Reply

Marsh Posté le 04-08-2006 à 16:44:10    

anapajari a écrit :

Tu splittes ton motif sur les retour à la ligne.
Tu testes uniquement si tu trouves une occurence de la 1ère ligne du motif dans ton fichier si oui tu testes les lignes suivantes si tout est bon tu récupères le numéro de la ligne qui matchait la 1ere ligne de ton motif.


Le problème d'une solution comme ça, c'est que tu risques d'avoir du mal à gérer les cas dans lesquels la première ligne du motif apparait plusieurs fois à la suite dans le fichier de log. Quitte à se lancer dans une solution "compliquée", autant programmer directement l'automate fini qui fait la recherche de la suite de lignes en question. C'est moins facile à coder, mais ça permet d'éviter de gérer "à la main" tous les cas particuliers un peu tordus.


---------------
TriScale innov
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed