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 :

Généraliser script pour plusieurs fichiers


Sujet :

Langage Perl

  1. #1
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 36
    Points : 29
    Points
    29
    Par défaut Généraliser script pour plusieurs fichiers
    Bonjour à tous,
    Je dois vérifier que mes résultats sont cohérents. Pour se faire j'essaye de parser un fichier csv qui contient mes résultats et je dois vérifers des contraintes (>=, <=) pour vérifier que tout marche bien.

    Voilà mon format de fichier :

    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
     
    FILE1
    var1;var2;var3;var4;var5;var6;var7;var8;var9;var10;var11
    0.01;0.8;0.6;670;48;108;1218;19.25;20.09;22.79;0.72
    0.01;0.95;0.6;255;48;108;1218;18.765;19.41;22.40;0.72
    0.01;0.9;0.6;285;48;108;1218;18.815;19.47;21.66;0.67
    0.05;0.8;0.6;194;0;12;546;3.285;3.87;4.71;0.41
    0.05;0.95;0.6;36;0;12;546;3.455;4.06;5.08;0.30
    0.05;0.9;0.6;63;0;12;546;3.332;3.80;4.73;0.42
    0.1;0.8;0.6;117;0;12;352;2.876;3.28;4.23;0.34
    0.1;0.95;0.6;27;0;12;266;2.643;3.10;3.92;0.39
    0.1;0.9;0.6;54;0;12;343;2.732;3.14;4.06;0.34
    0.2;0.8;0.6;54;0;12;198;0.72;1.18;1.84;0.13
    0.2;0.95;0.6;27;0;12;72;0.677;1.14;1.86;0.14
    0.2;0.9;0.6;33;0;12;108;0.755;1.03;1.70;0.11
     
     
     
     
    FILE2
    var1;var2;var3;var4;var5;var6;var7;var8;var9;var10;var11
    0.01;0.8;0.6;150;0;0;0;0.215;0.50;0.92;0.07
    0.01;0.95;0.6;96;0;0;0;0.181;0.45;0.77;0.07
    0.01;0.9;0.6;129;0;0;0;0.206;0.45;0.80;0.07
    0.05;0.8;0.6;150;0;0;0;0.211;0.45;0.82;0.07
    0.05;0.95;0.6;96;0;0;0;0.209;0.45;0.81;0.06
    0.05;0.9;0.6;129;0;0;0;0.211;0.45;0.78;0.08
    0.1;0.8;0.6;150;0;0;0;0.206;0.59;0.95;0.08
    0.1;0.95;0.6;96;0;0;0;0.249;0.56;1.01;0.08
    0.1;0.9;0.6;129;0;0;0;0.251;0.72;1.15;0.07
    0.2;0.8;0.6;129;0;0;39;0.17;0.45;0.78;0.07
    0.2;0.95;0.6;85;0;0;21;0.169;0.55;0.85;0.07
    0.2;0.9;0.6;112;0;0;21;0.169;0.42;0.77;0.07
    Et voilà mon code :
    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
    #! /usr/bin/perl
    $normal = "/home/lovelace/Bureau/verification/resultats.csv";
     
    open(RESULT,"$normal") or die "Unable to open";
    my (@var1, @var2, @var3, @var4, @var5, @var6, @var7);
    $ct = 1;
    while (my $line = <RESULT>){
    	if($line =~ /^[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/) {
    		chomp $line;
    		$var1[$ct] = $1 if $line =~ /^([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;
    		$var2[$ct] = $1 if $line =~ /^[0-9.]+;([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;	
    		$var3[$ct] = $1 if $line =~ /^[0-9.]+;[0-9.]+;([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;
    		$var4[$ct] = $1 if $line =~ /^[0-9.]+;[0-9.]+;[0-9.]+;([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;
    		$var5[$ct] = $1 if $line =~ /^[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;
    		$var6[$ct] = $1 if $line =~ /^[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;
    		$var7[$ct] = $1 if $line =~ /^[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;
    		$ct++;
    	}
    }
    close RESULT;
    $fail = 0;
    for ($i=1; $i<$ct && $fail == 0; $i++){
    	#print "$var1[$i];$var2[$i];$var3[$i];$var4[$i];$var5[$i];$var6[$i];$var7[$i]\n";
    	for ($j=$i+1; $j<$ct && $fail == 0; $j++){
    		if(($var1[$i] == $var1[$j]) && ($var2[$i] == $var2[$j])){
    			if(($var3[$i]>=$var3[$j]) && (($var4[$i]>$var4[$j]) || ($var5[$i]>$var5[$j]) || ($var6[$i]>$var6[$j]) || ($var7[$i]>$var7[$j]))){
    				print "FAIL with 3.1\n";
    				$fail = 1;
    			}
    			if(($var3[$i]<$var3[$j]) && (($var4[$i]<$var4[$j]) || ($var5[$i]<$var5[$j]) || ($var6[$i]<$var6[$j]) || ($var7[$i]<$var7[$j]))){
    				print "FAIL with 3.2\n";
    				$fail = 1;
    			}
    		}
     
    		if(($var1[$i] == $var1[$j]) && ($var3[$i] == $var3[$j])){
    			if(($var2[$i]>=$var2[$j]) && (($var4[$i]>$var4[$j]) || ($var5[$i]>$var5[$j]) || ($var6[$i]>$var6[$j]) || ($var7[$i]>$var7[$j]))){
    				print "FAIL with 2.1\n";
    				$fail = 1;
    			}
    			if(($var2[$i]<$var2[$j]) && (($var4[$i]<$var4[$j]) || ($var5[$i]<$var5[$j]) || ($var6[$i]<$var6[$j]) || ($var7[$i]<$var7[$j]))){
    				print "FAIL with 2.2\n";
    				$fail = 1;
    			}
    		}
     
    		if(($var2[$i] == $var2[$j]) && ($var3[$i] == $var3[$j])){
    			if(($var1[$i]>=$var1[$j]) && (($var4[$i]>$var4[$j]) || ($var5[$i]>$var5[$j]) || ($var6[$i]>$var6[$j]) || ($var7[$i]>$var7[$j]))){
    				print "FAIL with 1.1\n";
    				$fail = 1;
    			}
    			if(($var1[$i]<$var1[$j]) && (($var4[$i]<$var4[$j]) || ($var5[$i]<$var5[$j]) || ($var6[$i]<$var6[$j]) || ($var7[$i]<$var7[$j]))){
    				print "FAIL with 1.2\n";
    				$fail = 1;
    			}
    		}
    	}
    }
     
    if ($fail == 0){
    	print"SUCCESS\n";
    	$fail = 1;
    }
    Mon code fonctionne quand je n'ai qu'un seul bloc (FILE1) dans mon fichier résultat. Le problème vient quand j'en ai deux (FILE1 et FILE2), car il ne faut pas qu'il compare des résultats pour des fichiers résultats différents. Et je ne sais pas comment lui dire de faire ceci.

    Pouvez vous m'aider s'il vous plaît?
    Par ailleurs n'y a t'il pas une méthode plus simple et propre pour faire mes regex?

    Bonne soirée

  2. #2
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Sur les regex:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if($line =~ /^[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/)
    peut se réécrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if($line =~ /^([0-9.]+;){11}$/;
    Sur les suivantes, tu as déjà vérifié que ta ligne était conforme, il te suffit de capturer le premier motif reconnu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $var1[$ct] = $1 if $line =~ /^([0-9.]+);/;
    Sur l'autre point, arrête la lecture de ton fichier quand tu rencontres FILE 2, fais ton traitement (et recommence tout à 0 après si besoin).

  3. #3
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 36
    Points : 29
    Points
    29
    Par défaut
    Merci Lolo78 pour ton aide.

    Avec ton if je ne rentre plus dans la boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if($line =~ /^([0-9.]+;){11}$/){
    Sur les suivantes, tu as déjà vérifié que ta ligne était conforme, il te suffit de capturer le premier motif reconnu:
    Pour $var1 cela marche bien, mais comment je fais pour les autres?

    Sur l'autre point, arrête la lecture de ton fichier quand tu rencontres FILE 2, fais ton traitement (et recommence tout à 0 après si besoin).
    Effectivement c'est exactement cela qu'il faut que je fasse cela mais je ne sais pas comment faire, car le nom des fichiers va varier.
    A l'heure actuelle j'arrive à récupérer le nom du fichier mais je ne vois pas comment continuer :

    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
    65
    66
    67
    68
    #! /usr/bin/perl
    $normal = "/home/lovelace/Bureau/verification/resultats.csv";
     
    open(RESULT,"$normal") or die "Unable to open";
    my (@var1, @var2, @var3, @var4, @var5, @var6, @var7, $file);
    $ct = 1;
    while (my $line = <RESULT>){
    	if($line =~ /^(\w+)$/){
    		$file = $1 if $line =~ /^(\w+)$/;
    		print "$file\n";
    	}
    	#if($line =~ /^([0-9.]+;){11}$/){
    	if($line =~ /^[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/){
    		chomp $line;
    		$var1[$ct] = $1 if $line =~ /^([0-9.]+);/;
    		$var2[$ct] = $1 if $line =~ /^[0-9.]+;([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;	
    		$var3[$ct] = $1 if $line =~ /^[0-9.]+;[0-9.]+;([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;
    		$var4[$ct] = $1 if $line =~ /^[0-9.]+;[0-9.]+;[0-9.]+;([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;
    		$var5[$ct] = $1 if $line =~ /^[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;
    		$var6[$ct] = $1 if $line =~ /^[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;
    		$var7[$ct] = $1 if $line =~ /^[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+;([0-9.]+);[0-9.]+;[0-9.]+;[0-9.]+;[0-9.]+$/;
    		$ct++;
    	}
    }
    close RESULT;
    $fail = 0;
    for ($i=1; $i<$ct && $fail == 0; $i++){
    	#print "$var1[$i];$var2[$i];$var3[$i];$var4[$i];$var5[$i];$var6[$i];$var7[$i]\n";
    	for ($j=$i+1; $j<$ct && $fail == 0; $j++){
    		if(($var1[$i] == $var1[$j]) && ($var2[$i] == $var2[$j])){
    			if(($var3[$i]>=$var3[$j]) && (($var4[$i]>$var4[$j]) || ($var5[$i]>$var5[$j]) || ($var6[$i]>$var6[$j]) || ($var7[$i]>$var7[$j]))){
    				print "FAIL with 3.1\n";
    				$fail = 1;
    			}
    			if(($var3[$i]<$var3[$j]) && (($var4[$i]<$var4[$j]) || ($var5[$i]<$var5[$j]) || ($var6[$i]<$var6[$j]) || ($var7[$i]<$var7[$j]))){
    				print "FAIL with 3.2\n";
    				$fail = 1;
    			}
    		}
     
    		if(($var1[$i] == $var1[$j]) && ($var3[$i] == $var3[$j])){
    			if(($var2[$i]>=$var2[$j]) && (($var4[$i]>$var4[$j]) || ($var5[$i]>$var5[$j]) || ($var6[$i]>$var6[$j]) || ($var7[$i]>$var7[$j]))){
    				print "FAIL with 2.1\n";
    				$fail = 1;
    			}
    			if(($var2[$i]<$var2[$j]) && (($var4[$i]<$var4[$j]) || ($var5[$i]<$var5[$j]) || ($var6[$i]<$var6[$j]) || ($var7[$i]<$var7[$j]))){
    				print "FAIL with 2.2\n";
    				$fail = 1;
    			}
    		}
     
    		if(($var2[$i] == $var2[$j]) && ($var3[$i] == $var3[$j])){
    			if(($var1[$i]>=$var1[$j]) && (($var4[$i]>$var4[$j]) || ($var5[$i]>$var5[$j]) || ($var6[$i]>$var6[$j]) || ($var7[$i]>$var7[$j]))){
    				print "FAIL with 1.1\n";
    				$fail = 1;
    			}
    			if(($var1[$i]<$var1[$j]) && (($var4[$i]<$var4[$j]) || ($var5[$i]<$var5[$j]) || ($var6[$i]<$var6[$j]) || ($var7[$i]<$var7[$j]))){
    				print "FAIL with 1.2\n";
    				$fail = 1;
    			}
    		}
    	}
    }
     
    if ($fail == 0){
    	print"SUCCESS\n";
    	$fail = 1;
    }
    Bonne journée

  4. #4
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lovelace63 Voir le message
    Merci Lolo78 pour ton aide.

    Avec ton if je ne rentre plus dans la boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if($line =~ /^([0-9.]+;){11}$/){
    Exact, je n'avais pas vu que le dernier champ n'avait pas de point-virgule. Cela devient:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($line =~ /^([0-9.]+;){10}([0-9.]+)$/) {
    Là, j'ai testé, ça marche.

    Citation Envoyé par lovelace63 Voir le message
    Pour $var1 cela marche bien, mais comment je fais pour les autres?
    Pardon, j'avais mal lu tes expressions régulières (pas vu que la paire de parenthèses se déplaçait à chaque fois).

    Tu peux essayer cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @var = (undef, $1, $2, $3, $4, $5, $6, $7) if $line =~ /^([0-9.]+;){10}([0-9.]+)$/;
    Tu utilises ensuite le tableau temporaire @var pour remplir tes @var1, @var2, etc.

    Ou même directement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ($var1[$ct], $var2[$ct], ... $var7[$ct] ) = ($1, $2, $3, $4, $5, $6, $7) if $line =~ /^([0-9.]+;)+/
    Mais je pense que tu devrais utiliser un tableau de tableaux, plutôt que tes tableaux var1, var2, etc.

  5. #5
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Pour gérer tes fichiers, je ferais sans doute deux boucles while imbriquée: une qui lit le fichier, les lignes vides et les noms de fichiers, et une boucle intérieur qui lit uniquement les lignes de données; dès que l'on arrive à une ligne vide, on traite les données collectée jusqu'à présent, puis on sort de la boucle while interne.

    Quelque chose comme cela:

    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
    while (my $line = <RESULT>){
            next if $line =~ /^\s*$/; # on ne traite pas les lignes vides
    	if($line =~ /^(\w+)$/){
    		$file = $1 if $line =~ /^(\w+)$/;
    		print "$file\n";
    	}
            while ($line = <RESULT>) {
                    # ici le code avec tes expressions régulières pour remplir tes tableaux ...
     
                    if ($line =~ /^\s*$/) { # ligne vide, on est à la fin d'un fichier
                            traite_fichier(); # dans cette routine le code pour traiter l'ensemble des lignes d'un fichier
                            last; # sort de la boucle while intérieure
                     }
            }
    }
    Ce n'est pas testé, il faut peut-être ajuster une ou deux choses, mais ça donne l'idée générale.

  6. #6
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 36
    Points : 29
    Points
    29
    Par défaut
    Tout à l'air de fonctionner.
    Merci beaucoup

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

Discussions similaires

  1. 1 ctl pour plusieurs fichier, plusieurs tables
    Par cathou9999 dans le forum Administration
    Réponses: 3
    Dernier message: 10/05/2007, 16h18
  2. Browse pour plusieur fichiers
    Par Mirna dans le forum MFC
    Réponses: 2
    Dernier message: 18/10/2006, 22h45
  3. script pour parsing fichier xml
    Par Melvine dans le forum Modules
    Réponses: 4
    Dernier message: 06/10/2006, 18h47
  4. [VBA-E]une macro unique pour plusieurs fichiers excel
    Par fanchic29 dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 21/04/2006, 16h20
  5. Autorun pour plusieurs fichiers en simultané sur clé USB
    Par princebaal dans le forum Windows
    Réponses: 1
    Dernier message: 06/10/2005, 13h35

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