IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Question sur l'ordre du "match"


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 198
    Par défaut Question sur l'ordre du "match"
    Bonjour,

    je viens avec une question générale et non un script à débugger.

    C'est concernant le "match", il peut arriver que l'on veuille "matcher" ce qui suit un symbole, nom.
    Mais si dans les lignes il y a plusieurs fois le caractère précéde le résultat recherché ?
    Y a t'il un moyen de "matcher" tel caractère à partir du 3è qui se présente par exemple.

    Sur internet j'avais trouvé cet exemple qui match après le signe "=" (même si dans ce cas les /g je ne comprend pas ce qu'ils font la mais sans ca ne marche pas)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    my $_ = 'b=var1+var2';
    # force further /g matches to start after the first '='
    /=/g;
     
    while (/(\w+)/g) {
        print "$1\n";
    }
    #Résultat
    var1
    var2


    Mais si par exemple on prend un fichier de log comme ci-dessous et l'on veut récupérer dans des variables tel ou tel valeur après tel ou tel signe ":" par exemple ?

    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of
    interface: fxp0.0Name of protocol: TCP, Packet Length: 50824, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 1020, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513

    J'ai été assez clair dans la question?

    merci pour l'éclairage à venir ou solution plus simple proposée.

  2. #2
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2013
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 247
    Par défaut
    avec des expressions régulières je pense que ça peut le faire du genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ( $_ =~ /^Time\s*of\s*Log\s*:(.*):(.*):(.*)$/ )
    si tu dis la(es) partie(s) que tu veux récupérer, on pourra plus t'aider

  3. #3
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    A partir de perl 5.10, tu peux utiliser les assertions postfix ou prefix, qui recherchent un motif suivant ou précédent un autre motif (avec la limitation que le motif à suivre ou précéder doit être de taille fixe).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    my $request = "field1:toto; field2:titi";
    foreach my $field ($request =~ /(?<=:)(\w+)/g) {
      say $field;
    }
    donne

  4. #4
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 352
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 352
    Par défaut
    On peut l'expression sous forme de pseudo-index, voici un exemple qui récupére tout depuis le niéme ':' jusqu'a la fin de la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    perl -n -e '/^([^:]*:){3}(.*)/ ; print $2."\n"' log
    En rouge, il suffit de changer le 3 par celui a partir duquel tu veux récupérer le reste de la ligne.
    Si ce n'est pas le reste de la ligne qui t'interresse, il suffit de modifier la partie bleue.

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 198
    Par défaut
    Merci pour vos réponses

    J'ai une préférence pour les solutions de Philou67430 et disedorgue car elles évites trop de modifications si on tombe sur un autre format.

    Sur la solution de Philou, tous les résultat sont affichés car tous le même nom de variable. Ains il n'y a pas de différence pour faire un choix du résultat à affiché.
    Un peu comme dans la ligne CLI de disedorgue.

    J'essaye de faire un mixte des deux pour arriver au résultat final

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my $request = "field1:toto; field2:titi";
    say $1 if $request =~ /^([^:]*:){2}(\w+)/ ;
    Résultat
    toto sans la suite, c'est bon

    Par contre si je veux capturer deux valeur ? (ici titi et tata que j'ai rajouté)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my $request = "field1:toto; field2:titi; field3:tata";
    say $2  $3 if $request =~ /^([^:]*:){2}(\w+){3}(\w+)/ ;
    Résultat ...pas terrible
    t i

    J'ai essayé de le faire en deux fois mais idem

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    my $request = "field1:toto; field2:titi; field3:tata";
    my $var1 = $request =~ /^([^:]*:){2}(\w+)/;
    my $var2 = $request =~ /^([^:]*:){3}(\w+)/;
    say "$var1\t$var2";
    Résultat
    1 1

  6. #6
    Membre chevronné Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Par défaut
    Citation Envoyé par caramon _majere Voir le message
    J'ai une préférence pour les solutions de Philou67430 et disedorgue car elles évites trop de modifications si on tombe sur un autre format.
    ? [EDIT : ok, je n'avais pas vu ton message de 15:43 ]

    ...J'ai essayé de le faire en deux fois mais idem...
    c'est à ça que sert /g...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Taisha:~/tttmp/parselog $ perl -E 'my $request = q{field1:toto; field2:titi; field3:tata}; say "$1 => $2" while $request =~ /([^:;]+):\s*([^;]+);?\s*/g'
    field1 => toto
    field2 => titi
    field3 => tata
    Taisha:~/tttmp/parselog $

  7. #7
    Membre chevronné Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Par défaut
    Citation Envoyé par cmcmc Voir le message
    c'est à ça que sert /g...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Taisha:~/tttmp/parselog $ perl -E 'my $request = q{field1:toto; field2:titi; field3:tata}; say "$1 => $2" while $request =~ /([^:;]+):\s*([^;]+);?\s*/g'
    field1 => toto
    field2 => titi
    field3 => tata
    Taisha:~/tttmp/parselog $
    une version plus safe, qui sort en erreur si on n'a pas analysé l'intégralité de la ligne (note les ancrages au début par \G et en fin par $)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Taisha:~/tttmp/parselog $ perl -E 'my $request = q{field1:toto; field2:titi; field3:tata}; say "$1 => $2" while $request =~ /\G([^:;]+):\s*([^;]+)(?:(?:;\s*)|(?:\s*$))/gc; die q{echec en position }, pos($request), q{ à partir de [}, substr($request, pos($request), 10), q{]} if pos($request) < length($request)'
    field1 => toto
    field2 => titi
    field3 => tata
    Taisha:~/tttmp/parselog $ perl -E 'my $request = q{field1:toto; field2:titi; field3:tata; blearch}; say "$1 => $2" while $request =~ /\G([^:;]+):\s*([^;]+)(?:(?:;\s*)|(?:\s*$))/gc; die q{echec en position }, pos($request), q{ à partir de [}, substr($request, pos($request), 10), q{]} if pos($request) < length($request)'
    echec en position 39 à partir de [blearch] at -e line 1.
    field1 => toto
    field2 => titi
    field3 => tata
    Taisha:~/tttmp/parselog $

  8. #8
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Pour reprendre ce que j'avais écrit, et récupérer le 3 éléments suivant ":", tu peux écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    my $request = "field1:toto; field2:titi; field3:tata";
    say [$request =~ /(?<=:)(\w+)/g]->[2];
    Si tu veux récupérer à la fois ce qui est avant le ":" et ce qui est après, tu peux simplement écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my $request = "field1:toto; field2:titi; field3:tata";
    say [$request =~ /(\w+:\w+)/g]->[2];
    ou bien travailler avec des split, ou bien encore écrire comme dans le message précédent de cmcmc.

  9. #9
    Membre chevronné Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    my $request = "field1:toto; field2:titi; field3:tata";
    say [$request =~ /(\w+:\w+)/g]->[2];
    Amateurs de copies surnuméraires, bonjour

    Pour les autres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Taisha:~/tttmp/parselog $ perl -E 'my $request = "field1:toto; field2:titi; field3:tata"; say +($request =~ /(\w+:\w+)/g)[2];'
    field3:tata
    Taisha:~/tttmp/parselog $
    Ok, je sors

  10. #10
    Membre chevronné Avatar de cmcmc
    Homme Profil pro
    Inscrit en
    Juillet 2013
    Messages
    316
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 316
    Par défaut
    Citation Envoyé par caramon _majere Voir le message
    Bonjour,

    je viens avec une question générale et non un script à débugger.

    C'est concernant le "match", il peut arriver que l'on veuille "matcher" ce qui suit un symbole, nom.
    Mais si dans les lignes il y a plusieurs fois le caractère précéde le résultat recherché ?
    Y a t'il un moyen de "matcher" tel caractère à partir du 3è qui se présente par exemple.

    Sur internet j'avais trouvé cet exemple qui match après le signe "=" (même si dans ce cas les /g je ne comprend pas ce qu'ils font la mais sans ca ne marche pas)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    my $_ = 'b=var1+var2';
    # force further /g matches to start after the first '='
    /=/g;
     
    while (/(\w+)/g) {
        print "$1\n";
    }
    #Résultat
    var1
    var2
    le suffix /g signifie 'global' et permet de faire plusieurs match successifs en progressant dans une même chaîne.

    Ici, le premier match (/=/g) démarre du début de la chaîne, et s'arrête quand il a trouvé un caractère '='. La position de départ pour les prochains matches appliqués sur cette chaîne avec le suffix /g sera celle du caractère suivant et est accessible par la fonction pos :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Taisha:~/tttmp $ perl -E '$str = q{foo = bar + qux}; $str =~ m/=/g; say pos($str)'
    5
    Taisha:~/tttmp $
    Cette fonction permet également de positionner explicitement le point de démarrage de la recherche dans la chaîne. En cas d'échec du match, la position est remise à '', sauf si on utilise le suffixe c, auquel cas elle contient la position du caractère suivant le dernier match
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Taisha:~/tttmp $ perl -E '$str = q{foo = bar + qux}; pos($str) = 5; @vars = $str =~ m/(\w+)/gc; say "@vars"; say q{pos est maintenant }, pos($str)'
    bar qux
    pos est maintenant 15
    Taisha:~/tttmp $
    Mais si par exemple on prend un fichier de log comme ci-dessous et l'on veut récupérer dans des variables tel ou tel valeur après tel ou tel signe ":" par exemple ?

    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of
    interface: fxp0.0Name of protocol: TCP, Packet Length: 50824, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 1020, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513

    J'ai été assez clair dans la question?

    merci pour l'éclairage à venir ou solution plus simple proposée.
    A vue de nez, ce que tu as ici ce sont des couples clé: valeur séparés par des ',', et c'est probablement comme ça qu'il faut prendre le problème. La clé ne semble pas pouvoir contenir ':', donc on peut utiliser split pour décomposer un couple, en utilisant le 3eme paramètre (limite) pour ne pas découper sur les ':' pouvant apparaître dans les valeurs (séparateur heure:minutes:secondes par exemple).

    Ce log est un peu pénible si les lignes forment en fait des groupes. Je considère que c'est le cas, et qu'un groupe commence par 'Time of Log'.

    Après correction triviale du log au début :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of 
    interface: fxp0.0Name of protocol: TCP, Packet Length: 50824, Source address: 172.17.22.108:829,
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 50824, Source address: 172.17.22.108:829,
    (comme les autres),
    le code ci-dessous
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    # -*- Mode: cperl; coding: utf-8; tab-width: 8; indent-tabs-mode: nil; cperl-indent-level: 4 -*-
    # parse1.pl
    use strict;
    use warnings;
    use Data::Dumper;
     
    my @entries;
    {
        local $/ = 'Time of Log';
        while (my $text = <DATA>) {
    	next if $text eq $/;
    	$text =~ s{$/$}{};
    	$text = $/ . $text;
    	$text =~ s/\n/,/sg;
    	my %pairs = map { split /:\s*/s, $_, 2 } split /\s*,\s*/s, $text;
    	push @entries, \%pairs;
        }
    }
    print Data::Dumper->Dump([\@entries], [qw(*entries)]);
     
    __DATA__
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 50824, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 1020, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    produit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    Taisha:~/tttmp/parselog $ perl parse1.pl
    @entries = (
                 {
                   'Name of protocol' => 'TCP',
                   'Name of interface' => 'fxp0.0',
                   'Time of Log' => '2004-10-13 10:37:17 PDT',
                   'Filter' => 'f',
                   'Filter action' => 'accept',
                   'Source address' => '172.17.22.108:829',
                   'Destination address' => '192.168.70.66:513',
                   'Packet Length' => '50824'
                 },
                 {
                   'Name of protocol' => 'TCP',
                   'Name of interface' => 'fxp0.0',
                   'Time of Log' => '2004-10-13 10:37:17 PDT',
                   'Filter' => 'f',
                   'Filter action' => 'accept',
                   'Source address' => '172.17.22.108:829',
                   'Destination address' => '192.168.70.66:513',
                   'Packet Length' => '1020'
                 },
                 {
                   'Name of protocol' => 'TCP',
                   'Name of interface' => 'fxp0.0',
                   'Time of Log' => '2004-10-13 10:37:17 PDT',
                   'Filter' => 'f',
                   'Filter action' => 'accept',
                   'Source address' => '172.17.22.108:829',
                   'Destination address' => '192.168.70.66:513',
                   'Packet Length' => '49245'
                 },
                 {
                   'Name of protocol' => 'TCP',
                   'Name of interface' => 'fxp0.0',
                   'Time of Log' => '2004-10-13 10:37:17 PDT',
                   'Filter' => 'f',
                   'Filter action' => 'accept',
                   'Source address' => '172.17.22.108:829',
                   'Destination address' => '192.168.70.66:513',
                   'Packet Length' => '49245'
                 },
                 {
                   'Name of protocol' => 'TCP',
                   'Name of interface' => 'fxp0.0',
                   'Time of Log' => '2004-10-13 10:37:17 PDT',
                   'Filter' => 'f',
                   'Filter action' => 'accept',
                   'Source address' => '172.17.22.108:829',
                   'Destination address' => '192.168.70.66:513',
                   'Packet Length' => '49245'
                 },
                 {
                   'Name of protocol' => 'TCP',
                   'Name of interface' => 'fxp0.0',
                   'Time of Log' => '2004-10-13 10:37:17 PDT',
                   'Filter' => 'f',
                   'Filter action' => 'accept',
                   'Source address' => '172.17.22.108:829',
                   'Destination address' => '192.168.70.66:513',
                   'Packet Length' => '49245'
                 }
               );
    Taisha:~/tttmp/parselog $
    Sinon on peut bien sûr construire plutôt une structure hiérarchique mais ça ne semble pas nécessaire ici...

  11. #11
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mai 2013
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2013
    Messages : 198
    Par défaut
    Citation Envoyé par cmcmc Voir le message
    le suffix /g signifie 'global' et permet de faire plusieurs match successifs en progressant dans une même chaîne.

    Ici, le premier match (/=/g) démarre du début de la chaîne, et s'arrête quand il a trouvé un caractère '='. La position de départ pour les prochains matches appliqués sur cette chaîne avec le suffix /g sera celle du caractère suivant et est accessible par la fonction pos :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Taisha:~/tttmp $ perl -E '$str = q{foo = bar + qux}; $str =~ m/=/g; say pos($str)'
    5
    Taisha:~/tttmp $
    Cette fonction permet également de positionner explicitement le point de démarrage de la recherche dans la chaîne. En cas d'échec du match, la position est remise à '', sauf si on utilise le suffixe c, auquel cas elle contient la position du caractère suivant le dernier match
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Taisha:~/tttmp $ perl -E '$str = q{foo = bar + qux}; pos($str) = 5; @vars = $str =~ m/(\w+)/gc; say "@vars"; say q{pos est maintenant }, pos($str)'
    bar qux
    pos est maintenant 15
    Taisha:~/tttmp $


    A vue de nez, ce que tu as ici ce sont des couples clé: valeur séparés par des ',', et c'est probablement comme ça qu'il faut prendre le problème. La clé ne semble pas pouvoir contenir ':', donc on peut utiliser split pour décomposer un couple, en utilisant le 3eme paramètre (limite) pour ne pas découper sur les ':' pouvant apparaître dans les valeurs (séparateur heure:minutes:secondes par exemple).

    Ce log est un peu pénible si les lignes forment en fait des groupes. Je considère que c'est le cas, et qu'un groupe commence par 'Time of Log'.

    Après correction triviale du log au début :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of 
    interface: fxp0.0Name of protocol: TCP, Packet Length: 50824, Source address: 172.17.22.108:829,
    en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 50824, Source address: 172.17.22.108:829,
    (comme les autres),
    le code ci-dessous
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    # -*- Mode: cperl; coding: utf-8; tab-width: 8; indent-tabs-mode: nil; cperl-indent-level: 4 -*-
    # parse1.pl
    use strict;
    use warnings;
    use Data::Dumper;
     
    my @entries;
    {
        local $/ = 'Time of Log';
        while (my $text = <DATA>) {
    	next if $text eq $/;
    	$text =~ s{$/$}{};
    	$text = $/ . $text;
    	$text =~ s/\n/,/sg;
    	my %pairs = map { split /:\s*/s, $_, 2 } split /\s*,\s*/s, $text;
    	push @entries, \%pairs;
        }
    }
    print Data::Dumper->Dump([\@entries], [qw(*entries)]);
     
    __DATA__
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 50824, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 1020, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    Time of Log: 2004-10-13 10:37:17 PDT, Filter: f, Filter action: accept, Name of interface: fxp0.0
    Name of protocol: TCP, Packet Length: 49245, Source address: 172.17.22.108:829,
    Destination address: 192.168.70.66:513
    produit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    Taisha:~/tttmp/parselog $ perl parse1.pl
    @entries = (
                 {
                   'Name of protocol' => 'TCP',
                   'Name of interface' => 'fxp0.0',
                   'Time of Log' => '2004-10-13 10:37:17 PDT',
                   'Filter' => 'f',
                   'Filter action' => 'accept',
                   'Source address' => '172.17.22.108:829',
                   'Destination address' => '192.168.70.66:513',
                   'Packet Length' => '50824'
                 },
                 {
                   'Name of protocol' => 'TCP',
                   'Name of interface' => 'fxp0.0',
                   'Time of Log' => '2004-10-13 10:37:17 PDT',
                   'Filter' => 'f',
                   'Filter action' => 'accept',
                   'Source address' => '172.17.22.108:829',
                   'Destination address' => '192.168.70.66:513',
                   'Packet Length' => '1020'
                 },
                 {
                   'Name of protocol' => 'TCP',
                   'Name of interface' => 'fxp0.0',
                   'Time of Log' => '2004-10-13 10:37:17 PDT',
                   'Filter' => 'f',
                   'Filter action' => 'accept',
                   'Source address' => '172.17.22.108:829',
                   'Destination address' => '192.168.70.66:513',
                   'Packet Length' => '49245'
                 },
                 {
                   'Name of protocol' => 'TCP',
                   'Name of interface' => 'fxp0.0',
                   'Time of Log' => '2004-10-13 10:37:17 PDT',
                   'Filter' => 'f',
                   'Filter action' => 'accept',
                   'Source address' => '172.17.22.108:829',
                   'Destination address' => '192.168.70.66:513',
                   'Packet Length' => '49245'
                 },
                 {
                   'Name of protocol' => 'TCP',
                   'Name of interface' => 'fxp0.0',
                   'Time of Log' => '2004-10-13 10:37:17 PDT',
                   'Filter' => 'f',
                   'Filter action' => 'accept',
                   'Source address' => '172.17.22.108:829',
                   'Destination address' => '192.168.70.66:513',
                   'Packet Length' => '49245'
                 },
                 {
                   'Name of protocol' => 'TCP',
                   'Name of interface' => 'fxp0.0',
                   'Time of Log' => '2004-10-13 10:37:17 PDT',
                   'Filter' => 'f',
                   'Filter action' => 'accept',
                   'Source address' => '172.17.22.108:829',
                   'Destination address' => '192.168.70.66:513',
                   'Packet Length' => '49245'
                 }
               );
    Taisha:~/tttmp/parselog $
    Sinon on peut bien sûr construire plutôt une structure hiérarchique mais ça ne semble pas nécessaire ici...

    ouch, je vois l'idée mais étant un newbie en perl, je comptais passer du temps sur le mécanisme des expression régulières plus haut mais la j'ai mal au crâne sans alcool

    Ca fera de quoi étudier

    Je n'avais pas vu ta réponse et avait répondu avant sur les réponses précédentes ...Mes résultats étaient plus modestes

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Petite question sur l'ordre des déclarations en python.
    Par vmonteco dans le forum Général Python
    Réponses: 6
    Dernier message: 05/09/2014, 11h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo