1
votes

Lire un fichier journal en perl et trouver la valeur entre crochets

J'ai un logfile.txt qui contient le journal d'exécution d'un certain testcase. Un exemple de ce fichier est présenté ci-dessous. Bien qu'il comporte de nombreuses autres lignes, mais je les ai supprimées par souci de simplicité.

Dans ce logfile.txt , mon objectif final est d'obtenir la valeur hexadécimale entre crochets dans la dernière ligne .

J'ai écrit un exemple de code en PERL pour rechercher la dernière ligne et l'imprimer mais je suis incapable de formuler l'expression régulière pour obtenir la valeur souhaitée.

Mon code:

0x0

INPUT

   > cat logfile.txt

Waiting for the completion of job..
.
.
.
.
.


The job has completed, returning [0x0]

OUTPUT strong>

#!/usr/bin/perl

my $logfile = "/path/to/logfile.txt";
open ( IN1 , $logfile) or die "Cannot find the file $logfile \n";
while (<IN1>)
    {
        chomp ($_);
        print $_ if ($_ =~ m/The job has completed/i);
    }
close (IN1);


1 commentaires

Essayez-le comme ceci \ [\ K0 [xX] [0-9a-fA-F] + (? = \])


3 Réponses :


4
votes

Quelque chose comme ceci:

#!/usr/bin/perl

use strict;
use warnings;

open my $log_fh, '<', 'logfile.txt' or die $!;

while (<$log_fh>) {
  print $1 if /The job has completed.+\[(.+)\]/;
}

J'ai utilisé des parenthèses ( (...) ) pour "capturer" tout ce qui apparaît entre [ code> et ] . Lorsque l'expression régulière correspond, le texte capturé sera stocké dans $1.

Remarque, j'ai également mis à jour votre code pour utiliser un idiome plus moderne pour ouvrir les fichiers. I a) utiliser un descripteur de fichier lexical, b) utiliser la version à trois arguments de open () et c) vérifier la valeur de retour de open () et tuer le programme si il échoue.


3 commentaires

@Yash: Eh bien, je sais que ça marche! Mais, plus important encore, l'avez-vous compris? :-)


oui je l'ai compris. je voulais juste préciser que dans la méthode ci-dessus, il n'est pas obligatoire de fermer le descripteur de fichier?


@Yash: Eh bien, il n'est jamais obligatoire de fermer () un descripteur de fichier. Mais l'un des avantages de l'utilisation d'une variable lexicale est que le descripteur de fichier sera automatiquement fermé lorsque la variable sort de la portée (ou, dans ce cas, lorsque le programme se termine).



4
votes

Pour faire correspondre la dernière ligne comprenant le début de votre phrase, vous pouvez utiliser:

^The job has completed,.*?\[\K0[xX][0-9a-fA-F]+(?=\])

Démo Regex

Cela correspondra à:

  • ^ Le travail est terminé, Correspond littéralement à partir du début de la chaîne
  • . *? Correspond à n'importe quel caractère non gourmand
  • \ [\ K Faites correspondre un crochet ouvrant et oubliez ce qui a été mis en correspondance en utilisant \K
  • 0 [xX] [0-9a-fA-F] + Correspond à un nombre hexadécimal
  • (? = \]) Recherche positive pour vérifier que ce qui suit est un crochet fermant


0 commentaires

0
votes

Essayez ce one-liner Perl

$  perl -lne ' if(eof) { /The job has completed.*\[(.*)\].*/ and print "Hex = $1" } ' logfile.txt
Hex = 0x0
$

Plus court .. Merci @Dave Cross

$ perl -lne ' if(eof) { /\[(.*)\]/ and print "Hex = $1" } ' logfile.txt
Hex = 0x0
$

Si vous voulez être sûr " Le travail est terminé "à la dernière ligne, puis

$ perl -lne ' if(eof) { /.*\[(.*)\].*/ and print "Hex = $1" } ' logfile.txt
Hex = 0x0
$


1 commentaires

Il n'y a pas besoin du premier ou du dernier . * dans votre regex.