[Perl] Besoin d'aide

barichon -  
 Barichon -
Bonjour a tous,

je débute dans la programmation, je suis nul mais j'essaye d'apprendre...
Je suis actuellement sur un script perl, l'objectif est de lire un fichier qui se presentent sous cette forme:

xxxxxxxxx:yyyyyyyyyy
lllllllllllllll:ppppppppp
zzzz:ooooooo

Je veut lire ce fichier (ca c'est ok) et recupérer dans un tableau1 xxxxxxxxx
llllllllllll
zzzzzzz

et récupérer dansun tableau 2: yyyyyyyyyyyyy
ppppppppp
oooooooooo

voici le debut de mon script, je suis bloqué a cette étape de lecture pourriez vous m'aidez svp.

!/usr/bin/perl


open(FIC,"/etc/apache2/vhost.conf") or die ("Erreur lors de l'ouverture du fichier.conf");

@fic = <FIC> ;
foreach $line (@fic)
{
   print $line;
}
close("FIC");


Cdt,

Merci d'avance.
Configuration: Linux
Mozilla 1.9.0.14

41 réponses

  • 1
  • 2
  • 3
Résumé de la discussion

Un débutant en programmation cherche à lire un fichier au format xxxxxxxxx:yyyyyyyyyy lllllllllllllll:ppppppppp zzzz:ooooooo et à constituer deux tableaux, l'un avec les premières valeurs et l'autre avec les secondes. La solution retenue passe par lire deux fichiers: access.log et vhost.conf, extraire les paires clé/valeur par délimiteur ':'; puis trier les lignes de access.log en fonction des clés présentes dans le premier tableau. On construit ensuite une structure de hachage pour regrouper les lignes associées à chaque clé et on affiche les résultats triés et les éléments non correspondants. Des échanges ultérieurs évoquent des tests dans divers environnements et soulignent l'importance d'adapter les droits et l'emplacement des fichiers (ex. tests en root, répertoires spécifiques) pour obtenir des résultats reproductibles.

Généré automatiquement par IA
sur la base des meilleures réponses
  1. fxta
     
    Et voila

    @lignes = ("");
    open(FILE, "<CHEMIN DE TON FICHIER");
    while(<FILE>){
    	push(@lignes,$_);
    }
    close(FILE);
    
    for(@lignes){
    	
    	@test = split(/:/, $_);
    	print "avant les : $test[0]\n";
    	print "apres les : $test[1]\n";
    }
    0
  2. barichon
     
    Merci beaucoup pour ta réponse !

    Cela marche très bien ! Merci encore !

    Cependant a la fin du script ca me print ça:

    avant les :
    
    Use of uninitialized value $test[1] in concatenation (.) or string at script.pl line 12.
    apres les :
    avant les :
    
    Use of uninitialized value $test[1] in concatenation (.) or string at script.pl line 12.
    apres les :
    avant les :
    
    Use of uninitialized value $test[1] in concatenation (.) or string at script.pl line 12.
    apres les :
    
    0
  3. barichon
     
    Bonsoir à tous et merci a fxta qui m'a aidé précedement, j'ai passé un bon nombre d'heures mais je cale sur la seconde phase de mon script, je n'y arrive vraiment pas...

    Celui ci doit lire un fichier acces.log qui se presente sous cette forme simplifié
    (c'est pas dur...je l'accorde...pas de souci sur ce point)

    ligne de log www.xxxxxxxxxxxxx.com cdfrzczfvretyhryh
    ligne de log www.lllllllllllllllllllll.com dedefdzfczerfzfzfr
    ligne de log www.zzzzz.com fcoàfjozrifjzopr 
    ligne de log www.lllllllllllllllllllll.com njnjnjnjnjijklpmvretyhryh
    ligne de log www.xxxxxxxxxxxxx.com aaaadfdcfkbhbkuljnl,pmyhryh
    ligne de log www.lllllllllllllllllllll.com mqaazsc
    


    Qui ensuite: (attention ça se corse mais grave !)

    A partir des éléments connu dans le tableau précedent $table[0] :

    xxxxxxxxx
                llllllllllllllllll
                zzzzzzzzzz
    


    Trie les lignes de ce log maniere décroissante (suivant le nombre d'occurence présente dans ce access.log)

    De tel sorte que si par exemple on a 3 fois llll 2 fois xxxx et 1 fois zzzzzz:

    ligne de log www.lllllllllllllllllllll.com njnjnjnjnjijklpmvretyhryh
    ligne de log www.lllllllllllllllllllll.com dedefdzfczerfzfzfr
    ligne de log www.lllllllllllllllllllll.com mqaazsc
    ligne de log www.xxxxxxxxxxxxx.com cdfrzczfvretyhryh
    ligne de log www.xxxxxxxxxxxxx.com aaaadfdcfkbhbkuljnl,pmyhryh
    ligne de log www.zzzzz.com fcoàfjozrifjzopr
    ligne de log www.nonpresent dans la table $table[0].com czefvrepv,epbt,eptb,eprm
    


    Je demande l'aide à quelq'un qui saurais m'aider, je suis pas le genre de mec a demander de l'aide pour un rien, j'avoue que c'est très important pour moi et que je suis HS quant aux compétences que ca demande...

    Merci d'avance,
    0
  4. barichon
     
    Ça à l'air compliquer masi ca se trouve yen a unu qui va me sortir un truc de dingue en 4 lignes...

    QQ1 peut me filer la patte ?
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    Pourquoi pas en utilisant directement le nom de domaine?

    #!/usr/bin/perl
    use strict;use warnings;
    my %h;/www\.(.*)\./ and push @{$h{$1}},$_ while (<DATA>);
    print @{$h{$_}} for (sort keys %h);
    __END__
    ligne de log www.xxxxxxxxxxxxx.com cdfrzczfvretyhryh
    ligne de log www.lllllllllllllllllllll.com dedefdzfczerfzfzfr
    ligne de log www.zzzzz.com fcoàfjozrifjzopr
    ligne de log www.lllllllllllllllllllll.com njnjnjnjnjijklpmvretyhryh
    ligne de log www.xxxxxxxxxxxxx.com aaaadfdcfkbhbkuljnl,pmyhryh
    ligne de log www.lllllllllllllllllllll.com mqaazsc


    Resultat
    lami20j@debian:~/trash/ccm_perl$ perl tri.pl
    ligne de log www.lllllllllllllllllllll.com dedefdzfczerfzfzfr
    ligne de log www.lllllllllllllllllllll.com njnjnjnjnjijklpmvretyhryh
    ligne de log www.lllllllllllllllllllll.com mqaazsc
    ligne de log www.xxxxxxxxxxxxx.com cdfrzczfvretyhryh
    ligne de log www.xxxxxxxxxxxxx.com aaaadfdcfkbhbkuljnl,pmyhryh
    ligne de log www.zzzzz.com fcoàfjozrifjzopr
    


    0
  7. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    A partir des éléments connu dans le tableau précedent $table[0] :
    Attention, $table[0], n'est pas un tableau.
    0
  8. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    Voici un exemple qui traite les deux cas

    Le script

    #!/usr/bin/perl
    use strict;use warnings;
    
    open F,"access.log"  or die "E/S: $!\n";
    open FF,"format.txt" or die "E/S: $!\n";
    
    # 1ère partie : obtenir les tableaux
    my (@f1,@f2,@reste,%h);
    push @f1,(split ":",$_)[0] and push @f2,(split ":",$_)[1] while(<FF>);
    chomp@f2;
    print "@f1@f2\n"; # maintenant tu as 2 tableaux
    
    # 2ème partie : faire le tri par rapport au tableau @f1
    while (<F>){
      /www\.(.*)\./;push @{$h{$1}},$_ if grep{/$1/} @f1;
      push @reste,$_ unless grep{/$1/}@f1;
    }
    print @{$h{$_}} for (sort keys %h);print "@reste";
    
    __END__
    


    Le fichier access.log

    ligne de log www.xxxxxxxxx.com cdfrzczfvretyhryh
    ligne de log www.lllllllllllllll.com dedefdzfczerfzfzfr
    ligne de log www.zzzz.com fcoàfjozrifjzopr
    ligne de log www.lllllllllllllll.com njnjnjnjnjijklpmvretyhryh
    ligne de log www.xxxxxxxxx.com aaaadfdcfkbhbkuljnl,pmyhryh
    ligne de log www.lllllllllllllll.com mqaazsc
    ligne de log www.nonpresent dans la table $table[0].com czefvrepv,epbt,eptb,eprm
    


    Le fichier format.txt
    lami20j@debian:~/trash/ccm_perl$ cat format.txt
    xxxxxxxxx:yyyyyyyyyy
    lllllllllllllll:ppppppppp
    zzzz:ooooooo
    


    Exécution du script

    lami20j@debian:~/trash/ccm_perl$ perl tri2.pl
    xxxxxxxxx lllllllllllllll zzzz
    yyyyyyyyyy ppppppppp ooooooo
    ligne de log www.lllllllllllllll.com dedefdzfczerfzfzfr
    ligne de log www.lllllllllllllll.com njnjnjnjnjijklpmvretyhryh
    ligne de log www.lllllllllllllll.com mqaazsc
    ligne de log www.xxxxxxxxx.com cdfrzczfvretyhryh
    ligne de log www.xxxxxxxxx.com aaaadfdcfkbhbkuljnl,pmyhryh
    ligne de log www.zzzz.com fcoàfjozrifjzopr
    ligne de log www.nonpresent dans la table $table[0].com czefvrepv,epbt,eptb,eprm
    
    0
  9. barichon
     
    MERCI, un grand merci pour ton aide !!!!!!!!

    Génial :)

    Heu un pti truc qui change, genre si mon fichier de log a un te comme ca sans les "www.":

    llllllllllllllll.com dedefdzfczerfzfzfr
    llllllllllllllll.com njnjnjnjnjijklpmvretyhryh
    lllllllllllllll.com mqaazsc
    xxxxxxxxx.com cdfrzczfvretyhryh
    xxxxxxxxx.com aaaadfdcfkbhbkuljnl,pmyhryh
    zzzz.com fcoàfjozrifjzopr
    nonpresent dans la table $table[0].com czefvrepv,epbt,eptb,eprm
    


    ca donne koi ?

    Merci de ton aide encore une fois !
    0
  10. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    Le script
    En gras tu as les modifications
    #!/usr/bin/perl
    use strict;use warnings;
    
    open F,"access.log1"  or die "E/S: $!\n";
    open FF,"format.txt" or die "E/S: $!\n";
    
    # 1ère partie : obtenir les tableaux
    my (@f1,@f2,@reste,%h);
    push @f1,(split ":",$_)[0] and push @f2,(split ":",$_)[1] while(<FF>);
    chomp@f2;
    print "@f1\n@f2\n"; # maintenant tu as 2 tableaux
    
    # 2ème partie : faire le tri par rapport au tableau @f1
    while (<F>){
      /^(.*)\./;push @{$h{$1}},$_ if grep{/$1/} @f1;
      push @reste,$_ unless grep{/$1/}@f1;
    }
    print @{$h{$_}} for (sort keys %h);print "@reste";
    
    __END__
    


    Le fichier access.log1
    xxxxxxxxx.com cdfrzczfvretyhryh
    lllllllllllllll.com dedefdzfczerfzfzfr
    zzzz.com fcoàfjozrifjzopr
    lllllllllllllll.com njnjnjnjnjijklpmvretyhryh
    xxxxxxxxx.com aaaadfdcfkbhbkuljnl,pmyhryh
    lllllllllllllll.com mqaazsc
    nonpresent dans la table $table[0].com czefvrepv,epbt,eptb,eprm
    


    L'exécution

    lami20j@debian:~/trash/ccm_perl$ perl tri3.pl
    xxxxxxxxx lllllllllllllll zzzz
    yyyyyyyyyy ppppppppp ooooooo
    lllllllllllllll.com dedefdzfczerfzfzfr
    lllllllllllllll.com njnjnjnjnjijklpmvretyhryh
    lllllllllllllll.com mqaazsc
    xxxxxxxxx.com cdfrzczfvretyhryh
    xxxxxxxxx.com aaaadfdcfkbhbkuljnl,pmyhryh
    zzzz.com fcoàfjozrifjzopr
    nonpresent dans la table $table[0].com czefvrepv,epbt,eptb,eprm
    

    0
  11. barichon
     
    Merci lami20j tu veux pas m'apprendre nta magie ?

    Tu me fais rêver là !

    J'ai un petit problème car l'execution du script quand je print:

    print @{$h{$_}} for (sort keys %h);print "@reste";


    ca me dit:

    Unmatched ( in regex; marked by <-- HERE in blablabla at script5.pl line 15, <F> line 8.
    
    0
  12. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    Colle ici le script que tu exécutes.
    0
  13. barichon
     
    tiens regarde j'execute ceci:

    #!/usr/bin/perl
    use strict;use warnings;

    open F,"access.log"  or die "E/S: $!\n";
    open FF,"vhost.conf" or die "E/S: $!\n";
    
    # 1ère partie : obtenir les tableaux
    my (@f1,@f2,@reste,%h);
    push @f1,(split ":",$_)[0] and push @f2,(split ":",$_)[1] while(<FF>);
    chomp@f2;
    print "@f1\n@f2\n"; # maintenant tu as 2 tableaux
    
    # 2ème partie : faire le tri par rapport au tableau @f1
    while (<F>){
      /^(.*)\./;push @{$h{$1}},$_ if grep{/$1/} @f1;
      push @reste,$_ unless grep{/$1/}@f1;
    }
    print @{$h{$_}} for (sort keys %h);print "@reste";
    
    __END__
    
    0
  14. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    Affiche le résultat de
    perl -cx /chemin/vers/tonscript
    0
  15. barichon
     
    romain@romain:/etc/apache2$ perl -cx /etc/apache2/script5.pl
    /etc/apache2/script5.pl syntax OK
    0
  16. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    Pour voir ce qui ne va pas, j'ai besoin de tes 2 fichiers, access.log et vhost.conf
    0
  17. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    En ce qui concerne le message d'erreur n'était pas complet (vu la confidentialité de message), donc je ne pouvais pas savoir pourquoi.

    En fait par exemple dans la ligne 8 comme le montre le message d'erreur, on voit qu'elle commence avec quelque chose de genre

    sous-nom.domaine.fr xx.x.xxx.xx

    Dans la regex de script je capture jusqu'au 1er point vu ton exemple llllllllllllllll.com dedefdzfczerfzfzfr
    Donc au lieu de trouver correctement sous-nom.domaine.fr la regex trouve seulement sous-nom

    Voici un script qui doit fonctionner (les modifications en gras)
    #!/usr/bin/perl
    use strict;use warnings;
    
    open F,"access.log"  or die "E/S: $!\n";
    open FF,"vhost.conf" or die "E/S: $!\n";
    
    # 1ère partie : obtenir les tableaux
    my (@f1,@f2,@reste,%h);
    push @f1,(split ":",$_)[0] and push @f2,(split ":",$_)[1] while(<FF>);
    chomp@f2;
    #print "@f1\n@f2\n"; # maintenant tu as 2 tableaux
    
    # 2ème partie : faire le tri par rapport au tableau @f1
    while (<F>){
              /^(.*?)\s/;push @{$h{$1}},$_ if grep{/$1/} @f1;
                push @reste,$_ unless grep{/$1/}@f1;
    }
    print @{$h{$_}} for (sort keys %h);print for @reste;
    
    __END__


    0
  18. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    Comme le tri se faisait seulement selon le nom de domaine, j'ai remarque que le tri n'est pas fait pour les IP
    Voici une version qui fait le tri correctement sur la ligne entière
    #!/usr/bin/perl
    use strict;use warnings;
    
    open F,"access.log"  or die "E/S: $!\n";
    open FF,"vhost.conf" or die "E/S: $!\n";
    
    # 1ère partie : obtenir les tableaux
    my (@f1,@f2,@reste,%h);
    push @f1,(split ":",$_)[0] and push @f2,(split ":",$_)[1] while(<FF>);
    chomp@f2;
    #print "@f1\n@f2\n"; # maintenant tu as 2 tableaux
    
    # 2ème partie : faire le tri par rapport au tableau @f1
    while (<F>){
              /^(.*?)\s/;push @{$h{$1}},$_ if grep{/$1/} @f1;
                push @reste,$_ unless grep{/$1/}@f1;
    }
    print sort @{$h{$_}} for (sort keys %h);print for sort @reste;
    
    __END__

    0
  19. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    Ca doit être bon maintenant

    #!/usr/bin/perl
    use strict;use warnings;
    
    open F,"access.log"  or die "E/S: $!\n";
    open FF,"vhost.conf" or die "E/S: $!\n";
    
    # 1ère partie : obtenir les tableaux
    my (@f1,@f2,@reste,%h);
    push @f1,(split ":",$_)[0] and push @f2,(split ":",$_)[1] while(<FF>);
    chomp@f2;
    
    # 2ème partie : faire le tri par rapport au tableau @f1
    while (<F>){
              /^(.*?)\s/;push @{$h{$1}},$_ if grep{/$1/} @f1;
                push @reste,$_ unless grep{/$1/}@f1;
    }
    
    my @trie = map  { $_->[1] }
               sort { $b->[0] <=> $a->[0] }
               map  { [ @$_+0, $_ ] } values %h;
    
    print sort @$_ for @trie;print for sort @reste;
    __END__
    
    0
  • 1
  • 2
  • 3