Forum Programmation.perl Mon script saute des lignes

Posté par  .
Étiquettes : aucune
-2
15
déc.
2009
Bonjour,

Avec pas beaucoup d'expérience en perl , je me suis aperçu que mon script sautait des lignes de mon fichier à traiter.
Comment y remédier?
Il commence comme ceci

line: while ( ) {
chop;
@Fld = split( ' ', $_, 9999 );

# lines we can ignore ???
if ( scalar( @Fld ) < 4 ) { # ignore these
next line;
}

# extract time from input line
$timestamp = $Fld[1];
# keep track of the last time found
$timestampN = $timestamp;
# convert time to seconds

# extract IN, OUT, or TIMESTAMP from input line
$inout = $Fld[3];
$s = ':', $inout =~ s/$s//g;
  • # plusieurs question

    Posté par  . Évalué à 3.

    pourquoi 9999 dans le split ?


    # lines we can ignore ???
    if ( scalar( @Fld ) < 4 ) { # ignore these
    next line;
    }

    C'est pas ça tout simplement ?
    scalar(@Fld) renvoi la le nombre de case du tableau il me semble ( j'ai un préférence pour $# mais bon :D ) < 4 donc si y a pas 4 champs dans une ligne elle est ignoré

    enfin en perl, il existe une directive qui est indispensable, notamment lorsqu'on débute : en début de programme, avant la première ligne

    use strict;

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

    • [^] # Reponses

      Posté par  . Évalué à 1.

      Merci Fearan,

      J'ai commenté les lignes et c'est toujours la même chose ....
      Note, qu'il saute toujours les mêmes lignes.

      En ce qui concerne le use strict;
      Cela génère des bugs, car j'ai donné un extrait du code que je pensais pertinent. Notamment sur la ligne suivante :
      if $running_under_some_shell;
      avec l'erreur suivante :
      Global symbol "$running_under_some_shell" requires explicit package name at flexCount.pl line 45.
      BEGIN not safe after errors--compilation aborted at flexCount.pl line 55.

      Je n'ai pas voulu en mettre tout le script, il faut quand même que je bosse dessus.... J'ai repris ce code afin de l'améliorer. Il compte le lapse de temps entre la sortie et le retour d'une licence de programme sur chaque utilisateur d'après la log du serveur. Il est constitué d'un batch shell qui met en forme (c'est un todo pour avoir qu'un seul fichier) ce dernier appel flexcount.pl. Je pense que l'erreur Global Symbol est liée à cela met je ne la comprend pas.
      J'espère ne pas vous avoir trop effrayé ....
      • [^] # Re: Reponses

        Posté par  . Évalué à 3.

        en fait le use strict impose que l'utilisation de variable ne puisse se faire que si elle a été préalablement déclarée.

        $plop="tonk" ;
        générera une erreur
        alors que
        my $plop="tonk";
        passera.
        selon le champs d'application de la variable tu peux aussi utiliser our (pour le package)

        Utiliser use strict, c'est se prémunir contre beaucoup d'étourderie en perl.

        pour le reste je ne vois pas où (a part la zone avec le next) mais vu que tu as commenté la partie en question et que ça continue de sauter des lignes, le saut doit être ailleurs.

        Il ne faut pas décorner les boeufs avant d'avoir semé le vent

  • # chop/chomp?

    Posté par  (site web personnel) . Évalué à 4.

    Hello,

    chop enlève le dernier caractère de la ligne, alors que chomp n'enlève le dernier caractère que si c'est un 'blanc' (cf http://perldoc.perl.org/5.8.8/functions/chomp.html ).
    Ca me surprendrait, mais est-ce que ça ne pourrait pas jouer?

    Sinon si tu peux poster un ou deux exemples de lignes qui sont bonnes et de lignes qui sautent alors qu'elles ne devraient pas, ça pourrait aider.
  • # Pas très clair, tes explications

    Posté par  . Évalué à 3.

    Avec pas beaucoup d'expérience en perl , je me suis aperçu que mon script sautait des lignes de mon fichier à traiter.

    if ( scalar( @Fld ) < 4 ) { next line; }

    Ici sachant que Fld comporte les données de ton fichier (je suppose, en fait, en l'occurrence, ça contient des données entrées en ligne de commande) et que si le nombre de champs n'est pas suffisant, on passe à la ligne suivante (ordre next) (c'est l'explication de fearan...)

    Par contre, on n'a pas de lignes de tests, genre un fichier de quelques lignes où tu montrerais quelles lignes sont zappées...

    Accessoirement (et comme fearan), je pense qu'il *faut* utiliser use strict; et que le "9999" dans le split est tout simplement très moche (à la rigueur mets -1)
  • # J'ai 2 fichier comparés

    Posté par  . Évalué à 1.

    En fait j'ai 2 fichiers de log dont j'ai comparés les résultats qui ne sont pas les mêmes alors qu'il devrait être égaux. Le premier fichier est original, donc l'activité de toto est mélangée avec les autres utilisateur, le deuxième fichier est la log original traitée pour n'avoir que l'activité de toto

    J'ai donc ajouté une ligne print après le chomp cela m'a montré que les lignes étaient bien lues mais pas traitées.
    Dans ce premier traitement toutes les log sont mélangées :
    Sorties 1 :

    13:57:13 (cdslmd) OUT: "300" toto@serveur
    14:02:01 (cdslmd) REMOVING toto@serveur:localhost:23.0 from 300
    14:02:01 (cdslmd) IN: "300" toto@serveur (USER_REMOVED)
    14:07:32 (cdslmd) OUT: "300" toto@serveur
    14:12:00 (cdslmd) REMOVING toto@serveur:localhost:23.0 from 300
    14:12:00 (cdslmd) IN: "300" toto@serveur (USER_REMOVED)
    toto@serveur 21-Oct-2008 14:07:32 2008 10 21 14 07 32
    toto@serveur 21-Oct-2008 14:12:00 2008 10 21 14 12 00
    toto@serveur 0 0 4 28
    14:18:49 (cdslmd) OUT: "300" toto@serveur
    14:22:01 (cdslmd) REMOVING toto@serveur:localhost:23.0 from 300
    14:22:01 (cdslmd) IN: "300" toto@serveur (USER_REMOVED)
    14:30:07 (cdslmd) OUT: "300" toto@serveur
    toto@serveur 21-Oct-2008 14:21:56 2008 10 21 14 21 56
    toto@serveur 21-Oct-2008 14:32:01 2008 10 21 14 32 01
    toto@serveur 0 0 10 5
    14:42:01 (cdslmd) REMOVING toto@serveur:localhost:23.0 from 300
    14:42:01 (cdslmd) IN: "300" toto@serveur (USER_REMOVED)
    15:13:55 (cdslmd) OUT: "300" toto@serveur
    15:22:01 (cdslmd) REMOVING toto@serveur:localhost:23.0 from 300
    15:22:01 (cdslmd) IN: "300" toto@serveur (USER_REMOVED)


    Sortie 2 :
    Ici j'ai modifié la log en triant préalablement l'activité de l'utlisateur toto :

    13:57:13 (cdslmd) OUT: "300" toto@serveur
    14:02:01 (cdslmd) REMOVING toto@serveur:localhost:23.0 from 300
    14:02:01 (cdslmd) IN: "300" toto@serveur (USER_REMOVED)
    toto@serveur 21-Oct-2008 13:57:13 2008 10 21 13 57 13
    toto@serveur 21-Oct-2008 14:02:01 2008 10 21 14 02 01
    toto@serveur 0 0 4 48
    14:07:32 (cdslmd) OUT: "300" toto@serveur
    14:12:00 (cdslmd) REMOVING toto@serveur:localhost:23.0 from 300
    14:12:00 (cdslmd) IN: "300" toto@serveur (USER_REMOVED)
    toto@serveur 21-Oct-2008 14:07:32 2008 10 21 14 07 32
    toto@serveur 21-Oct-2008 14:12:00 2008 10 21 14 12 00
    toto@serveur 0 0 4 28
    14:18:49 (cdslmd) OUT: "300" toto@serveur
    14:22:01 (cdslmd) REMOVING toto@serveur:localhost:23.0 from 300
    14:22:01 (cdslmd) IN: "300" toto@serveur (USER_REMOVED)
    toto@serveur 21-Oct-2008 14:18:49 2008 10 21 14 18 49
    toto@serveur 21-Oct-2008 14:22:01 2008 10 21 14 22 01
    toto@serveur 0 0 3 12
    14:30:07 (cdslmd) OUT: "300" toto@serveur
    14:42:01 (cdslmd) REMOVING toto@serveur:localhost:23.0 from 300
    14:42:01 (cdslmd) IN: "300" toto@serveur (USER_REMOVED)
    toto@serveur 21-Oct-2008 14:30:07 2008 10 21 14 30 07
    toto@serveur 21-Oct-2008 14:42:01 2008 10 21 14 42 01
    toto@serveur 0 0 11 54
    15:13:55 (cdslmd) OUT: "300" toto@serveur
    15:22:01 (cdslmd) REMOVING toto@serveur:localhost:23.0 from 300
    15:22:01 (cdslmd) IN: "300" toto@serveur (USER_REMOVED)


    On voit clairement que certaine log sont traitées et d'autre pas, dans ce cas c'est plus profond dans le script.....
    • [^] # Re: J'ai 2 fichier comparés

      Posté par  (site web personnel) . Évalué à 2.

      J'avoue que le 'on voit clairement' n'est pas si clair que ça pour moi...
      je ne suis pas sur de comprendre quelle lignes ne sont pas traitées,

      Sinon, juste une idée en passant: si tu remplaces ' ' par /\s+/ dans ton split, est-ce que ça change quelque chose? Ça pourrait être le cas si tu as une tab à la place d'un espace, par exemple.
      • [^] # explication

        Posté par  . Évalué à 1.


        13:57:13 (cdslmd) OUT: "300" toto@serveur
        14:02:01 (cdslmd) REMOVING toto@serveur:localhost:23.0 from 300
        14:02:01 (cdslmd) IN: "300" toto@serveur (USER_REMOVED)

        Ce sont les lignes de la log


        toto@serveur 21-Oct-2008 13:57:13 2008 10 21 13 57 13
        toto@serveur 21-Oct-2008 14:02:01 2008 10 21 14 02 01
        toto@serveur 0 0 4 48

        Ce sont les lignes traitées, dans la troisième il y a la différence de temps entre le OUT et IN

        J'ai modifié le split comme ceci :

        @Fld = split( /\s+/ , $_, 9999 );


        Aucun changement..... .
        • [^] # Re: explication

          Posté par  (site web personnel) . Évalué à 2.

          Et si tu mets le print après le if()?

          Ça pourrait être que les lignes sont bien traitées mais que le traitement a un problème et qu'au final tu te retrouves avec une chaine vide, ce qui expliquerait pourquoi elle n'apparaissent pas.

          Si ce n'est pas ça, je pense aussi que le script n'est pas assez complet.
    • [^] # Re: J'ai 2 fichier comparés

      Posté par  . Évalué à 2.

      Bizarre dans ton script, tu vires toute ligne ne comprenant pas au moins 3 espaces puis pour les lignes conservées tu récupères le timestamp qui est en début de ligne.
      Les lignes qui ne sont pas prises en compte semblent être celles du type
      toto@serveur 21-Oct-2008 14:42:01 2008 10 21 14 42 01 ou
      toto@serveur 0 0 11 54


      or ce type de ligne aura du mal avec la suite de ton script (par exemple le premier champs n'est pas un timestamp)

      Je pense que tu as trop simplifié le code que tu nous as soumis, comme les autres, je ne vois pas ce qui est problématique.
      • [^] # Re: J'ai 2 fichier comparés

        Posté par  . Évalué à 1.

        En fait ce qui suit est le fichier de log :

        13:57:13 (cdslmd) OUT: "300" toto@serveur
        14:02:01 (cdslmd) REMOVING toto@serveur:localhost:23.0 from 300
        14:02:01 (cdslmd) IN: "300" toto@serveur (USER_REMOVED)

        Donc le script doit faire la différence et calculer le temps écouler entre le OUT et le IN. C'est apparemment ce qui se passe pour certain couple de ligne et pas pour d'autre car elle sont ignorées.

        Ce que je vous ai donné n'est pas le résultat final du script mais le flag debug.
  • # Dans ce cas partageons

    Posté par  . Évalué à 1.

    Il y a un peut prés 350 lignes, et je n'ai pas les droits de ce script, à part pour le modifier.

    Comment pourrais-je partager le code sur site du même style que : http://pix.toile-libre.org/


    Merci

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.