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 :

Découper fichier excel ou .csv


Sujet :

Langage Perl

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 28
    Points : 4
    Points
    4
    Par défaut Découper fichier excel ou .csv
    Bonjour à tous,


    Je viens de mettre au perl vu qu’on m’a souvent dit que ce langage était très pratique pour faire des recherches sur des fichiers.

    Cependant je suis bloqué à mon premier essai qu’est le suivant.

    J’ai ce fichier excel de la forme :

    Name IP Address Netmask Zone Comment
    h-1.1.1.1 1.1.1.1 255.255.255.255 Trust Test1
    h-2.2.2.2 2.2.2.2 255.255.255.255 Trust Test2
    ... ... ... ... ...

    Et je voudrais obtenir ce résultat :

    Name
    h-1.1.1.1
    h-2.2.2.2
    ...

    Mais je bloque complétement depuis quelques heures… Je ne sais même pas si le perl va me permettre de le faire, vu que je pars de fichiers excel…

    J'ai abordé le problème en commençant avec une boucle while sur le premier fichier excel (que j'ai passer en format txt pour rester simple au début) et j'ai essayé de print dans un nouveau fichier, mais je n'obtenais que des résultats bizarres comme une succession de chiffres hexadécimaux...

    J'ai vu qu'il existait des lib pour le perl traitant les fichiers excel avec cpan mais je voulais savoir si c'était possible de se débrouiller sans.

    Je pourrais aussi passer par un fichier .txt cependant en utilisant la commande awk j'ai pu noter que le fichier excel n'était alors pas composé de champs si je le passais en .txt....ce qui n'est alors pas pratique pour "couper" le fichier.

    Merci d’avance pour votre aide ^^ ! N'hésitez pas à me rediriger si nécessaire, ou bien à me donner des tutos!

    Artalis.

  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
    Oui, Perl permet tout-à-fait de réaliser ce que cherches à faire.

    Le mieux est d'utiliser un module spécialisé du CPAN: Spreadsheet:arseExcel.

    Sinon, une solution "artisanale" possible consisterait à exporter ("Enregistrer sous...") le fichier Excel dans un autre format, par exemple au format texte ou CSV et à exploiter le résultat.

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 28
    Points : 4
    Points
    4
    Par défaut
    Merci beaucoup pour ta réponse, je vais donc m'orienter vers le cpan.

    J'avais commencé en changeant le format de mon fichier en .txt mais cette transformation ne permettait pas de considérer les différentes colonnes comme différents champs, du coup c'était plus complexe pour faire la séparation. Comme je l'ai dit, pour ce cas là je pensais m'orienter vers des awk/grep etc... mais cela n'avait rien donné ^^.

    Je vous tiens au courant pour mon avancé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
    Sinon, avec les données d'exemples que tu as données:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    use strict;
    use warnings;
     
    while (<DATA>) {
         my $out = (split /\s+/, $_)[0];
         print $out, "\n";
    }
    __DATA__
    Name IP Address Netmask Zone Comment
    h-1.1.1.1 1.1.1.1 255.255.255.255 Trust Test1
    h-2.2.2.2 2.2.2.2 255.255.255.255 Trust Test2
    Ce qui donne à l'exécution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $ perl test_artalis.pl
    Name
    h-1.1.1.1
    h-2.2.2.2

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 28
    Points : 4
    Points
    4
    Par défaut
    Ton code correspond exactement à ce que je souhaitais faire.


    J'ai installé Spreadsheet... et j'étais en train d'essayer d'obtenir le résultat, mais je n'y avais pas encore réussi, du coup merci beaucoup ^^.

    Du coup, en utilisant ta méthode pour stocker le résultat dans un nouveau fichier .txt je fais comme ceci :

    use strict;
    use warnings;

    open(ADDRESS,"address.txt");
    open(FICHIER1,">addressuseless.txt");


    while (<ADDRESS>){
    my $out = (split /\s+/, $_)[0];
    print $out, "\n";
    print FICHIER1 $out, "\n" ;
    }

    close (ADDRESS);
    close(FICHIER1);

    Si jamais j'ai des erreurs de syntaxe, ou bien que le code n'est pas propre, n'hésitez pas à me le dire, je suis là pour apprendre ^^.

    Je vais continuer ce petit code en essayant d'effectuer une recherche de chacun des éléments récupérés en utilisant un autre fichier. Je vous tiens au courant.

  6. #6
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 28
    Points : 4
    Points
    4
    Par défaut
    Désolé pour le double post,

    mais voici la suite de mon script.

    Comme je l'ai indiqué précédemment, je souhaite maintenant voir si ce que j'ai récupéré dans mon FICHIER1 se trouve dans un autre fichier .txt : le fichier RULE. Il s'agit là encore d'un fichier avec plusieurs colonnes don't l'une possède des occurences d'adresses IP.

    Du coup, d'un point de vue algorithmique :

    je considère une ligne de FICHIER1
    je regarde si cette chaîne de caractères est présente dans RULE
    si ce n'est pas le cas, je supprime cette chaîne de caractères de FICHIER1

    Voici mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    open(RULE,"<rule.txt");
    open(FICHIER1,"<addressuseless.txt");
    while(<FICHIER1>){ #je souhaite tester toutes les lignes de FICHIER1
    	foreach my $lines(<RULE>){# je souhaite chercher l'occurence d'une ligne de FICHIER1 dans tout RULE
    		if(index($_,$lines)==-1){# si la ligne de FICHIER1 n'est pas dans ADDRESS alors je supprime cette ligne dans FICHIER
    			print $_="";
    			print "adresse non trouvee \n";
    		}
    	}
    }
    Cependant cela ne marche pas très bien vu que j'ai l'impression que seul la première ligne de FICHIER1 est passée en revue... De plus, elle n'est pas supprimée de mon fichier bien qu'elle ne soit pas présente dans RULE.

    Merci d'avance pour votre aide.

  7. #7
    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 : 58
    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
    Points : 5 753
    Points
    5 753
    Par défaut
    Tout d'abord, tu ouvres le fichier RULE en dehors de la boucle while(<FICHIER1>), ce qui fait qu'après avoir traité la première ligne du FICHIER1, tu ne liras plus rien dans le fichier RULE (puisqu'à la fin du traitement d'une ligne du FICHIER1, tout le fichier RULE est lu).

    Autre remarque : pourquoi ne pas faire ce filtrage à la source, dans la première partie du code.

    Enfin, si ton fichier RULE n'a pas une taille "astronomique" (disons inférieure à plusieurs centaines de Mo), tu peux le charger entièrement en mémoire sous forme d'une table de hashage (hash) dans laquelle les clés seront tes lignes du fichier RULE (chompées par exemple, c'est à dire sans le terminateur de ligne).
    Puis, pour chaque ligne du fichier address.txt, tu testes l'existence dans le hashage de la clé correspondant à la première colonne de ton fichier address.txt.

    Un peu comme ceci :

    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
    open my $RULE, "<", "rule.txt" or die "Can't open rule.txt for reading: $!";
    my %rule;
    while (my $rule = <$RULE>) {
      chomp($rule);
      $rule{$rule}++;
    }
     
    open my $ADDRESS, "<", "address.txt" or die "can't open address.txt for reading: $!";
    open my $FICHIER1,">", "addressuseless.txt" or die "Can't open addressuseless.txt for writing: $!";
    while (my $address = <$ADDRESS>) {
      chomp($address);
      my $out = (split /\s+/, $_)[0];
      if (exists $rule{$out}) {
        print $out, "\n";
        print FICHIER1 $out, "\n" ;
      }
    }
    (je n'ai pas testé ni compilé le code, il peut nécessiter des ajustements syntaxiques et fonctionnels)
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  8. #8
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 28
    Points : 4
    Points
    4
    Par défaut
    Merci pour ta rapide et complète réponse.

    Effectivement, on peut rassembler les 2 parties de code, je procédais juste par étape étant donné que je débute le perl.

    Sinon mon fichier RULE n'est pas très lourd 38kb, donc on peut le charger en mémoire. Je n'avais pas encore étudié les tables de hashage en perl, du coup cela ne m'était pas venu à l'esprit.

    Je vais tester ce que tu as proposé, et je vous tiens au courant.

    Merci encore.

    edit: cela n'a pas l'air de donner le résultat escompté. Cela compile bien, cependant je n'ai aucun résultat dans "addressuseless.txt" or la chaine de caractère "NAME" n'est pas dans RULE. Je pense d'ailleurs qu'il faut modifier ceci pour avoir quelque chose qui correspond à ce que je souhaite faire en théorie:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      if (exists $rule{$out}) {
        print $out, "\n";
      }
      else{
    	print $out;
    	print FICHIER1 $out, "\n" ;
    	} 
    }
    édit2: je viens de rajouter les lignes

    use strict;
    use warnings;

    et il y a quelques erreurs de syntaxe que je n'avais pas vues, je modifie et je vous tiens au courant.

    edit3:

    J'ai essayé de faire ce que j'au pu mais j'ai les erreurs suivantes qui apparaissent, et je ne sais pas torp comment les régler :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Name "main::FICHIER1" used only once: possible typo at scripttest_2.pl line 21.
    Use of uninitialized value $_ in split at scripttest_2.pl line 15, <$ADDRESS> line 1.
    Use of uninitialized value $out in exists at scripttest_2.pl line 16, <$ADDRESS> line 1.
    Use of uninitialized value $out in print at scripttest_2.pl line 20, <$ADDRESS> line 1.
    print() on unopened filehandle FICHIER1 at scripttest_2.pl line 21, <$ADDRESS> line 1.
    Use of uninitialized value $_ in split at scripttest_2.pl line 15, <$ADDRESS> line 2.
    Use of uninitialized value $out in exists at scripttest_2.pl line 17, <$ADDRESS> line 2.
    Use of uninitialized value $out in print at scripttest_2.pl line 21, <$ADDRESS> line 2.
    print() on unopened filehandle FICHIER1 at scripttest_2.pl line 22, <$ADDRESS> line 2.
    et cela pour toutes les "line".

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 28
    Points : 4
    Points
    4
    Par défaut
    Voilà du nouveau, après plusieurs essais qui n'étaient pas très convaincants, je pense obtenir une lise qui correspond à ce que je voulais.

    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
    use strict;
    use warnings;
     
    open my $RULE, "<", "rule.txt" or die "Can't open rule.txt for reading: $!";
    my %rule;
    while (my $rule = <$RULE>) {
      chomp($rule);
      $rule{$rule}++;
    }
     
    open (ADDRESS, "<", "address.txt") or die "can't open address.txt for reading: $!";
    open (FICHIER1,">", "addressuseless.txt") or die "Can't open addressuseless.txt for writing: $!";
    while (<ADDRESS>) {
      my $address=<ADDRESS>;
      chomp($address);
      my $out = (split /\s+/, $_)[0];
      if (exists $rule{$out}) {
        print FICHIER1 "address found \n";
    	}
       else{
       	print $out, "\n";
    	print FICHIER1 $out, "\n" ;
    	} 
     
    }
    Cependant j'ai 2 problemes.

    Avec le "adresse found", je ne comprends pas pourquoi il ne n'apparait pas dans mon fichier. Au début je pensais que la condition n'était jamais vérifiée, or ce n'est pas le cas.

    J'ai de plus l'erreur suivante, mais je ne sais pas trop comment la résoudre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Use of uninitialized value $address in scalar chomp at scripttest_2.pl line 15, <ADDRESS> line 473.
    edit:

    Finalement le problème du "address found" est un peu plus important que prévu. En effet, j'ai voulu entamer une nouvelle partie, qui consiste à partir d'un fichier contenant des noms de groupe d'adresses, et récupérer le nom de groupe qui apparaissait dans RULE. Il s'agit donc d'un print place non plus dans le else mais dans le if(exists...). Mais comme tout à l'heure, pas moyen de voir apparaitre le résultat... Voici du coup le code, c'est pratiquement la même chose qu'avant :

    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
    use strict;
    use warnings;
     
    open my $RULE,[........]print $out, "\n";
    		print FICHIER1 $out, "\n" ;
    	} 
    }
     
    open(ADDRESSGROUP,"<addressgroup.txt");
    open(FICHIERGROUP,">fichiergroup.txt");
     
    while (<ADDRESSGROUP>){#trouver tous les groupes d'adresses qui sont dans RULE et les stocker dans FICHIERGROUP
    	my $addressgroup=<ADDRESSGROUP>;
    	chomp($addressgroup);
    	my $out2 = (split /\s+/, $_)[0];
    	if(exists $rule{$out2}){
    		print $out2, "\n";
    		print FICHIERGROUP $out2, "\n";
    		}
    }
     
    close(ADDRESSGROUP);
    close(FICHIERGROUP);

  10. #10
    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 : 58
    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
    Points : 5 753
    Points
    5 753
    Par défaut
    Quand tu écris ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while (<ADDRESS>) {
      my $address=<ADDRESS>;
    Tu lis deux lignes de ADDRESS, mais une seule sera traitée dans $address.
    Tu dois donc écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while (my $address = <ADDRESS>) {
    Ensuite, je ne comprends pas bien ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (exists $rule{$out}) {
        print FICHIER1 "address found \n";
    	}
       else{
       	print $out, "\n";
    	print FICHIER1 $out, "\n" ;
    	}
    Tu testes l'existence de la règle, et si elle existe, tu écris "address found" dans FICHIER1, mais si elle n'existe pas, tu écris la règle dans FICHIER1... est-ce bien ce que tu voulais ?
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  11. #11
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 28
    Points : 4
    Points
    4
    Par défaut
    Merci pour la précision avec le "ADDRESS", je n'ai pas encore bien en main le perl ^^.


    Concernant la partie du code que tu ne comprends pas en fait c'est normal car j'ai rajouté le "address found" en plus pour voir si la condition était bien passée... Dans l'idée, il ne doit rien y avoir dans cette condition, vu que je veux supprimer les adresses qui sont dans RULE et non pas les remplacer par "adress found".

    Cependant, ayant eu besoin de débugger pas mal le code j'ai rajouté cela, et j'ai remarqué qu'en fait les adresses qui matchaient avec le if n'étaient pas remplacée, enfin, le "adress found" n'apparait pas dans mon FICHIER1.

    En gros, j'ai mon fichier (FICHIER1) avec des adresses, si elles apparaissent dans RULE, je dois les enlever du ficher avec les adresses ^^.

    Du coup, c'est le même problème pour le 2ème test portant sur les groupes d'adresses ( la condition étant dans ce cas dans le sens opposé), vu que je n'ai rien qui s'écrit avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	if(exists $rule{$out2}){
    		print $out2, "\n";
    		print FICHIERGROUP $out2, "\n";
    		}
    Du coup, j'aurais besoin de vos conseils pour résoudre ce problème, je dois rater quelque chose, mais je ne trouve pas quoi.

    Merci d'avance.

    edit: concernant la remarque pour le double ADDRESS, j'ai fait comme tu as indiqué, cependant ls script ne fonctionne plus ensuite, et je retrouve les erreurs de mon message précédent... du coup, il doit y avoir un probleme avec le "chomp"... Je vais étudier cela.

    édit2: a priori, le chomp fonctionne bien...mais le $out pose problème, je ne sais pas pourquoi j'ai "use of uninitialized value of $out" qui pop tout le temps... pourtant c'est exactement la meme chose que pour le premier script du début de la discussion...

    édit3: j'ai l'impression que cela fonctionne en remplaçant le $_ par $address. Alors après c'est plus par succession d'essais que j'ai trouvé plutot qu'en raisonnant. DOnc si quelqu'un avait une explication logique je suis preneur. Par contre, il faut que je teste mais je n'ai pas l'impression que la condition du if soit vérifée...alors que d'après le contenu des fichiers elle devrait l'etre.

    Je reposte mon code global pour avoir une base après tous les changements effcetués :

    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
    use strict;
    use warnings;
     
    open my $RULE, "<", "rule.txt" or die "Can't open rule.txt for reading: $!";
    my %rule;
    while (my $rule = <$RULE>) {
      chomp($rule);
      $rule{$rule}++;
    }
     
    open (ADDRESS, "<", "address.txt") or die "can't open address.txt for reading: $!";
    open (FICHIER1,">", "addressuseless.txt") or die "Can't open addressuseless.txt for writing: $!";
    while (my $address=<ADDRESS>) {#trouver toutes les adresses de ADDRESS qui ne sont pas dans RULE et les stocker dans FICHIER1 
    	chomp($address);
    	my $out = (split /\s+/, $address)[0];
    	if (exists $rule{$out}) {
    		print FICHIER1 "address found \n"; # à supprimer par la suite, n'est là que pour savoir si la condition passe ou pas
    		}
    		else{
    			print $out, "\n";
    			print FICHIER1 $out, "\n" ;
    		} 
    }
     
    open(ADDRESSGROUP,"<addressgroup.txt");
    open(FICHIERGROUP,">fichiergroup.txt");
     
    while (my $addressgroup=<ADDRESSGROUP>){#trouver tous les groupes d'adresses qui sont dans RULE et les stocker dans FICHIERGROUP
    	chomp($addressgroup);
    	my $out2 = (split /\s+/, $addressgroup)[0];
    	if(exists $rule{$out2}){
    		print $out2, "\n"; 
    		my $out3 = (split /\s+/, $addressgroup)[1];
    		print FICHIERGROUP $out3, "\n";
    		}
    }
     
    close(ADDRESSGROUP);
    close(FICHIERGROUP);

  12. #12
    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 : 58
    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
    Points : 5 753
    Points
    5 753
    Par défaut
    Exact, ça m'a m'avait échappé, dans cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $out = (split /\s+/, $_)[0];
    remplace le $_ par $address (puisque la ligne lue dans le fichier n'est pas dans $_, mais dans $address).
    Tu obtiens ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $out = (split /\s+/, $address)[0];
    Poste à nouveau ton code actuel en entier, et indiquer clairement ce qui ne va pas si c'est encore le cas.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  13. #13
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 28
    Points : 4
    Points
    4
    Par défaut
    J'avais édité mon message avec tout le code. Mais mon edit et ton nouveau message se sont croisés.

    Je reposte ici mon code pour que cela soit plus pratique:

    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
    use strict;
    use warnings;
     
    open my $RULE, "<", "rule.txt" or die "Can't open rule.txt for reading: $!";
    my %rule;
    while (my $rule = <$RULE>) {
      chomp($rule);
      $rule{$rule}++;
    }
     
    open (ADDRESS, "<", "address.txt") or die "can't open address.txt for reading: $!";
    open (FICHIER1,">", "addressuseless.txt") or die "Can't open addressuseless.txt for writing: $!";
    while (my $address=<ADDRESS>) {#trouver toutes les adresses de ADDRESS qui ne sont pas dans RULE et les stocker dans FICHIER1 
    	chomp($address);
    	my $out = (split /\s+/, $address)[0];
    	if (exists $rule{$out}) {
    		print FICHIER1 "address found \n"; # à supprimer par la suite, n'est là que pour savoir si la condition passe ou pas
    		}
    		else{
    			print $out, "\n";
    			print FICHIER1 $out, "\n" ;
    		} 
    }
     
    open(ADDRESSGROUP,"<addressgroup.txt");
    open(FICHIERGROUP,">fichiergroup.txt");
     
    while (my $addressgroup=<ADDRESSGROUP>){#trouver tous les groupes d'adresses qui sont dans RULE et les stocker dans FICHIERGROUP
    	chomp($addressgroup);
    	my $out2 = (split /\s+/, $addressgroup)[0];
    	print $out2, "\n";
    	if(exists $rule{$out2}){
    		print $out2, "\n"; 
    		my $out3 = (split /\s+/, $addressgroup)[1];
    		print FICHIERGROUP $out3, "\n";
    		}
    }
     
    close(ADDRESSGROUP);
    close(FICHIERGROUP);
    Les 2 problèmes sont les suivants :

    • La condition du "if" n'a pas l'air de fonctionner vu que le "address found" n'apparait qu'à la fin du fichier, et cela ne remplace pas les addresses qui sont et dans RULE et dans ADDRESS
    • J'ai un problème avec $out3 je n'ai pas l'impression qu'il reconnaisse la définition de $adressgroup (note: pour ce cas là je souhaite récupérer la 2ème colonne et non plus là première, cela vient peut etre de là...)
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      Use of uninitialized value $out3 in print at scripttest_2.pl line 35, <ADDRESSGROUP> line 22.

  14. #14
    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 : 58
    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
    Points : 5 753
    Points
    5 753
    Par défaut
    Il faut que tu fournisses des fichiers d'exemples (en pièce jointe ou en lien externe vers un hébergeur temporaire de fichiers), car là, il convient de débugger à l'aide du debugger (perl -d <script.pl> ...).
    En effet, difficile de voir "où" se situe le problème sans exemple concret ! (de plus, dans l'affichage de débug "address found", tu n'indiques aucune info supplémentaire qui pourrait être utile, comme le contenu de $out.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  15. #15
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 28
    Points : 4
    Points
    4
    Par défaut
    Voici avec des exemples de fichiers un résumé ^^ :

    Fichier ADDRESS:

    Name IP Address Netmask Zone Comment
    h-1.1.1.1 1.1.1.1 255.255.255.255 Trust Test1
    h-2.2.2.2 2.2.2.2 255.255.255 Trust Test2
    h-3.3.3.3 3.3.3.3 255.255.255.255 Trust Test3
    h-4.4.4.4 4.4.4.4 255.255.255.255 Trust Test4


    Fichier RULE:

    Num ID Logging Policy Action Source Zone Source Destination Zone Destination Service NAT Comment Rule
    1 5 Logging Permit Trust h-1.1.1.1 DMZ h-2.2.2.2 Groupe1 HTTP no Comment1 5
    2 3 Logging Permit DMZ h-2.2.2.2 Trust 2.2.2.2 HTTP no Comment2 3


    Fichier ADDRESSGROUP:

    Group Composed of Zone Comment
    Groupe1 h-1.1.1.1 h-2.2.2.2 Trust Comment1
    Groupe2 h-3.3.3.3 h-4.4.4.4 Untrust Comment2




    La première partie me permet donc d'obtenir les données de la première colonne du fichier ADDRESSE qui ne sont pas dans RULE. DOnc dans FICHIER1 je dois trouver ceci :


    Name
    h-3.3.3.3
    h-4.4.4.4


    Pour la 2ème partie de l'algorithme, je veux récupérer la 2ème colonne du fichier ADDRESSGROUP, donc connaître finalement les addresses contenues dans les groups qui se trouvent implicitement dans RULE soit le résultat suivant:


    Composed of
    h-1.1.1.1 h-2.2.2.2

    Voilà, j'espère que c'est un peu plus clair. Au passage, il ne faut pas chercher une logique pour les valeurs dans les tableaux, il s'agit d'exemples fictifs.

    Merci beaucoup pour votre aide.


    edit: je n'ai pas vu que tu avais besoin de fichiers externs, je te fais ca.
    Fichiers attachés Fichiers attachés

  16. #16
    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 : 58
    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
    Points : 5 753
    Points
    5 753
    Par défaut
    L'erreur du "address found" en fin de fichier vient d'une mauvaise écriture de ma part de la boucle while (je n'ai pas l'habitude d'utiliser cette construction, préférant souvent, peut-être à tord, utiliser un foreach).
    Il faut utiliser pour toutes les boucles while (y compris la première pour lire le fichier rule.txt) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while (defined(my $var = <FICHIER>)) {
    Je regarde le 2e pb maintenant.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  17. #17
    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 : 58
    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
    Points : 5 753
    Points
    5 753
    Par défaut
    Pour le 2e pb, j'ai un peu remanier le script :
    - les premières lignes du fichier d'entrée sont des entêtes, il faut soit les lire et les ignorer, soit les copier dans les fichiers de sortie
    - la forme à trois argument de open est préférable, de même que l'usage des FILE HANDLE sous forme de variable scalaire
    - je n'ai pas tout compris de la dernière boucle (voir mon commentaire # WHY WRITING ....). De plus, à la vue du contenu du fichier addressgroup, j'ai l'impression qu'il n'est pas possible de "spliter" les lignes avec un pattern /\s+/, car la 2e colonne contient semble-t-il plusieurs mots séparés par des espaces, mais à prendre comme une seule cellule. J'ai laissé tel quel en ajoutant cependant des vérifications sur l'existence des variables extraites.
    - l'erreur sur $out3 doit correspondre au fait que le fichier addressgroup.txt contient une ligne vide en fin de fichier

    Le script résultat :
    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
    use strict;
    use warnings;
     
    open my $RULE, "<", "rule.txt" or die "Can't open rule.txt for reading: $!";
    my %rule;
    <$RULE>; # Ignore the first line
    while (defined(my $rule = <$RULE>)) {
      chomp($rule);
      $rule{$rule}++;
    }
     
    open (my $ADDRESS, "<", "address.txt") or die "can't open address.txt for reading: $!";
    open (my $FICHIER1,">", "addressuseless.txt") or die "Can't open addressuseless.txt for writing: $!";
    print { $FICHIER1 } scalar(<$ADDRESS>); # Read and write the first line
    while (defined(my $address = <$ADDRESS>)) {#trouver toutes les adresses de ADDRESS qui ne sont pas dans RULE et les stocker dans FICHIER1 
    	chomp($address);
      if (defined(my $out = (split /\s+/, $address)[0])) {
        if (exists $rule{$out}) {
          print { $FICHIER1 } "address found \n"; # à supprimer par la suite, n'est là que pour savoir si la condition passe ou pas
    		}
    		else{
    			print $out, "\n";
    			print { $FICHIER1 } $out, "\n" ;
    		}
      }
      else {
        print "No address found at line $. [$address]\n";
      }
    }
     
    open (my $ADDRESSGROUP,"<", "addressgroup.txt") or die "Can't open addressgroup.txt for reading: $!";
    open (my $FICHIERGROUP,">", "fichiergroup.txt") or die "Can't open fichiergroup.txt for writing: $!";
     
    #trouver tous les groupes d'adresses qui sont dans RULE et les stocker dans FICHIERGROUP
    while (defined(my $addressgroup = <$ADDRESSGROUP>)) {
    	chomp($addressgroup);
      my ($out2, $out3) = (split /\s+/, $addressgroup)[0,1];
      if (defined $out2) {
        print $out2, "\n";
        if (exists $rule{$out2}){
          print $out2, "\n"; # WHY WRITING AGAIN out2 ???
          if (defined $out3) {
            print { $FICHIERGROUP } $out3, "\n";
          }
          else {
            print "No zone found at line $. in addressgroup.txt [$addressgroup]\n";
          }
    		}
      }
      else {
        print "No group found at line $. in addressgroup.txt [$addressgroup]";
      }
    }
     
    close($ADDRESSGROUP);
    close($FICHIERGROUP);
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  18. #18
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 28
    Points : 4
    Points
    4
    Par défaut
    Merci pour ta réponse, j'édite mon message avec les réponses à tes questions, ainsi que différents tests sur ce que tu as posté niveau code ^^.

    edit1:


    je viens juste de lancer ton script pour voir ce que cela donne, et je remarque que tu as toujours le même problème qu'avec le précédent script que j'avais posté.

    Il s'agit du contenu de "addressuseless.txt", donc FICHIER1. En effet, il ne devrait contenir que les adresses qui ne sont pas presentes dans RULE, soit la moitié des adresses (h-1.1.1.1 et h-2.2.2.2 sont dans RULE donc ne devraient pas arriver dans FICHIER1). Or le script inscrit toujours les 4 addresses (sans "address found" ce qui montre qu'il n'est jamais passé dans la boucle). Du coup je ne suis pas sur que la condition (exist $rule{$out}) soit vérifiée ou bien codée... C'est d'ailleurs pourquoi j'avais rajouté le "address found" pour voir si le programme passait dans cette boucle.

    Le but normalement étant donc de remplacer ensuite cette partie "adresse found" par une suppression du fichier adressuseless de l'adresse, pour ne conserver que les addresses qui ne se trouvent pas dans RULE, par exemple print $_="";

    Je ne sais pas si je suis assez clair, n'hésite pas à me le dire, n'arrivant pas à trouver le problem posé par ce "if", je suis prêt à réexpliquer ^^.




    Pour le "WHY WRINTING...", il s'agit là encore d'un test pour voir si je passé au moins une fois dans la boucle, or je n'ai jamais réussi à avoir ce cas là, car la condition bloque encore...

    Pour le "out3", effectivement, il y a plusieurs données dans la colonne, enfin plusieurs adresses/groupe, du coup, s'il avait été possible de récupérer toute la colonne, j'aurais ensuite remanié le fichier obtenu de la façon suivante pour avoir quelque chose de clair (je n'ai pas encore repris la syntaxe des open etc c'était surtout pour donner une vision):

    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
    open(FICHIERGROUP, "<", "fichiergroup.txt") or die "can't read $!";
    open(FICHIERGROUPALALIGNE, ">", "fichiergroupalaligne.txt") or die "can't create $!";
    while(<FICHIERGROUP>){#passe à la ligne à chaque nouvelle adresse
    	chomp($_);
    	$_=~ s/\s+/\n/g;
    	print FICHIERGROUPALALIGNE $_, "\n";
    }
    close(FICHIERGROUP);
    close(FICHIERGROUPALALIGNE);
     
    open(FICHIERGROUPALALIGNE,"<","fichiergroupalaligne.txt") or die "can't read $!";
    open(DONNEE, ">", "donnee.txt") or die "can't create $!";
    while(<FICHIERGROUPALALIGNE>){#supprime les lignes vides
    	next if /^\s*$/;
    	print DONNEE;
    }
     
    close(FICHIERGROUPALALIGNE);
    close(DONNEE);

    Je continue à regarder ton script, merci beaucoup en tout cas pour ton aide.

  19. #19
    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 : 58
    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
    Points : 5 753
    Points
    5 753
    Par défaut
    Je vais debugger la première partie, le filtrage des rules.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  20. #20
    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 : 58
    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
    Points : 5 753
    Points
    5 753
    Par défaut
    A première vue, tes fichiers ont un drôle d'encodage ... en tout cas, ce n'est pas de l'ASCII, ni de l'utf8. Ca semble être de l'UTF16 en little-endian.

    Pour les lire correctement, il va falloir faire une manip spéciale sur le file handle du fichier.

    Edit :
    Ensuite, ce fichier rule contient également des colonnes avec des valeurs. Tel qu'écrit actuellement, c'est la ligne entière qui sert de clé de recherche, or, ça ne semble pas correct. Quelle est la colonne de rule.txt qui sert de clé de recherche pour le fichier address.txt ?
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. Comment exporter un fichier Excel vers CSV
    Par machipot dans le forum VBA Access
    Réponses: 0
    Dernier message: 09/06/2008, 22h09
  2. Réponses: 1
    Dernier message: 30/12/2007, 14h51
  3. Convertion fichier excel en CSV
    Par ceaser dans le forum Excel
    Réponses: 1
    Dernier message: 23/05/2007, 14h56
  4. Exporter fichier Excel en .csv
    Par pierre.coudert dans le forum Windows
    Réponses: 7
    Dernier message: 27/02/2007, 13h45
  5. conversion de fichier Excel en csv ,
    Par bounette dans le forum Excel
    Réponses: 2
    Dernier message: 26/01/2005, 08h42

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