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 :

Traiter des fichiers à la chaîne dans un répertoire


Sujet :

Langage Perl

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Traiter des fichiers à la chaîne dans un répertoire
    Bonjour,

    Je suis débutant en Perl et j'ai l'impression d'être confronté à un problème simple pour tout le monde, mais que je n'arrive pourtant pas à détordre ; aussi j'espère que vous aurez cinq petites minutes pour m'expliquer ce qui ne va pas dans ma démarche.

    En gros, je cherche à appliquer un ensemble de traitements à un ensemble de fichiers contenus dans un seul répertoire.

    Ces traitements se résument (pour le moment) en deux subroutines simples qui permettent l'identification de la plus grosse font-size d'un document HTML et d'en ramener une portion de texte utile (le titre du document, le postulat étant que les plus gros caractères sont dans le titre).
    Ces subroutines fonctionnent très bien sur les fichiers que j'ai testé et j'ai donc souhaité les appliquer successivement à ces mêmes fichiers contenus dans un répertoire unique.

    Mon intention était d'utiliser un glob pour identifier les fichiers et leurs chemins d'accès, ce qui a l'air de fonctionner, mais leur ouverture par la suite semble poser problème - j'ai des résultats intranscriptibles sur mon premier fichier (il semble donc bien être lu), juste leur nom pour les autres.
    J'ai cherché partout (FAQ, cours, etc) pour en savoir plus sur le maniement du glob (j'ai aussi essayé avec opendir et readdir, pour tomber sur les mêmes résultats) et je ne trouve pas de solution à mon problème, depuis une semaine que je suis dessus. J'espère que vous pourrez m'aider, en pardonnant les erreurs éventuellement grossières du débutant que je suis.

    Voici le code (nb : tout ça est censé tourner sous Windows) :
    Code perl : 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
     
    $max=0;
    $SOURCE = "C:/toto/pouet/atraiter/*.htm";
     
    #lire et stocker le nom des fichiers 
     foreach (glob ($SOURCE)) {
     push(@listfic, $_);
    }
     
    #pour chaque fichier retrouvé, lancer l'exécution des subroutines
    foreach $entree (@listfic) {
    print "$entree\n";
    max();
    titre();
    }
     
    #identifier les font-size
    sub max {
    open IN,"< $entree" or die "On cherche encore, ce fichier n'existe po...\n";
    while(<IN>) {
       chomp; 
       if (/font-size[\D]*${max}[^>]+>([^<]+)/) {
    	print "$1\n";
    	}
    	if ($1>$max){
    	$max=$1;
    	}
    }
     
    close IN;
    }
     
    #extraire le titre, avec un peu de slurping pour ne pas s'encombrer des retours à la ligne
    sub titre {
    local ($/, *IN);
    open IN,"< $entree" or die "On cherche encore, ce fichier n'existe pas...\n";
    while(<IN>){
    	chomp;
    	if (/font-size: $max\D\D\W\W.*;\W\W([^<]+)/){
    	print "$1\n";
    	}
    }
     
     
    close IN;
    }

  2. #2
    Membre régulier
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2009
    Messages
    212
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Novembre 2009
    Messages : 212
    Points : 93
    Points
    93
    Par défaut
    salut,

    Perso je ne vois pas ce qui cloche dans ton script, je ne suis pas une experte mais plus une débutante ^^' surtout que je ne connais la fonction glob (j'irais jeter un coup d'oeil au passage)

    Toutefois j'ai eu à faire la même chose que toi et en cherchant sur le net j'étais tombé sur ce script (d'ailleur surment sur ce forum)

    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
     
    #/usr/bin/perl
     
    use strict;
    use warnings;
    use Cwd;
     
    my $dossier_courant= getcwd();#donne le chemin courant
     
    my $Repertoire = "$dossier_courant/$nom_repertoire";
    my @LesFichiers = ListersFichiers($Repertoire);
     
    sub ListersFichiers {
      my ( $repertoire ) = @_;
      my @fichiers;
     
      # Ouverture d'un répertoire
      opendir (my $FhRep, $repertoire) 
        or die "impossible d'ouvrir le répertoire $repertoire\n";
     
      # Liste fichiers et répertoire sauf (. et ..)
      my @Contenu = grep { !/^\.\.?$/ } readdir($FhRep);
     
      # Fermeture du répertoire
      closedir ($FhRep);
     
      # On récupère tous les fichiers
      foreach my $nom ( @Contenu ) {
        # Fichiers
        if ( -f "$repertoire/$nom") {
          push ( @fichiers, "$repertoire/$nom" );  
        }
        # Repertoires
        elsif ( -d "$repertoire/$nom") {
          # recursivité
          push ( @fichiers, ListersFichiers("$repertoire/$nom") );
        }
      }
     
      return @fichiers;
    }
    Je ne sais pas si tout ceci t'aide mais j'ai rien de mieux en réserve Si tu as des question hésite pas

  3. #3
    Membre averti
    Homme Profil pro
    Gérant infopsylon
    Inscrit en
    Juin 2010
    Messages
    215
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : Gérant infopsylon
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2010
    Messages : 215
    Points : 328
    Points
    328
    Par défaut
    Marlann,

    Je crois aussi que tu devrais t'orienter vers la solution d'angioedema, ca ne réglera peut-être pas ton problème, mais ca aura le mérite d'être un peu plus clean.
    Il y a beaucoups d'erreurs d'écriture dans ton script. A commencé par l'usage des variables, $entree, est globale, utilisée dans une boucle qui fait appel à une fonction, qui elle, l'utilisera... Soit tu places ta variable en locale, soit tu fait ton traitement dans ta boucle, au choix... Bref....

    Tu devrais vérifier l'encodage de tes fichiers HTML, UTF-8 ? ASCII ? UTF-16 ..., et aussi dans quel mode est ton script.

    Souvent, le fait d'avoir des caractères illisibles vient de ca.

    Cdlt,
    Lilian.

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Merci Angioedema, je vais voir ce que je peux faire avec ça . Ceci dit, ça ressemble très fort à la syntaxe du readdir que j'avais utilisée alternativement au glob, qui avait donné le même résultat.

    Merci aussi lilian_h, en ce qui concerne l'encodage j'avais fait attention au problème, ce n'en est pas l'origine ; pour ce qui est des variables globales, je pensais que justement leur intérêt était de pouvoir les utiliser partout. Quant au mode de script, j'avoue que là je ne vois pas de quoi tu parles . Je vais me renseigner...

    Je repasserai pour indiquer si j'ai eu le fin mot de l'affaire avec vos conseils.

  5. #5
    Membre averti
    Homme Profil pro
    Gérant infopsylon
    Inscrit en
    Juin 2010
    Messages
    215
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : Gérant infopsylon
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2010
    Messages : 215
    Points : 328
    Points
    328
    Par défaut
    Si toute fois il s'agit d'un problème d'encodage, je t'invite à lire une réponse de Jedai sur ce post:

    http://www.developpez.net/forums/d37...obleme-locale/

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Merci pour le thread lilian_h, j'y ai appris des trucs. Pour ma part, je me réfère à "Perl pour les linguistes" de L. Tanguy et N. Hathout chez Hermès-Lavoisier pour les problèmes d'encodage, c'est bien expliqué et assez exhaustif (pour des problématiques comme les miennes).

    Mais je crois définitivement que ce n'est pas ça mon problème.

    En fait, mes sub max et titre tournent bien (et donnent des résultats lisibles), sur un fichier pris isolément.
    De même, je peux trouver mes noms de fichier dans un répertoire (via un glob ou un readdir comme dans la solution d'angioedema).

    C'est quand j'essaie de faire tourner successivement mes sub sur chaque élément de la liste de fichiers que j'obtiens des résultats partiels (relatifs au premier ficihier de la liste) et imbitables.

    D'où je me suis dit que le problème de variables locales ou pas pourrait bien être celui qui pose problème, mais après essais, ça ne change strictement rien. Je reste donc dans le flou comme avant...

  7. #7
    Membre régulier
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2009
    Messages
    212
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Novembre 2009
    Messages : 212
    Points : 93
    Points
    93
    Par défaut
    sur ton code j'ai trouvé quelques petites choses qui me gène et que je n'avais pas vu la première fois. Je ne suis pas sure que les erreurs viennent de là mais bon
    Quand tu utilises une variable dans une sub (ou fonction) met la directement dedans, et lorsque tu utilises une variable dans ton code principale et que tu veux y travailler dessus avec une sub passe cette variable en paramètre. Ce qui donne ton code une fois corrigé (je ne met que les lignes corrigées)

    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
     
    #pour chaque fichier retrouvé, lancer l'exécution des subroutines
    foreach $entree (@listfic) {
    print "$entree\n";
    my $maxfct=max($entree);
    titre($entree,$maxfct);
    }
     
    #identifier les font-size
    sub max {
    my max = 0;
    open IN,"< $_[0]" or die "On cherche encore, ce fichier n'existe po...\n";
    while(<IN>) {
       chomp; 
       if (/font-size[\D]*${max}[^>]+>([^<]+)/) {
    	print "$1\n";
    	}
       if ($1>$max){
    	$max=$1;
    	}
       return $max;
    }
     
    close IN;
    }
     
    #extraire le titre, avec un peu de slurping pour ne pas s'encombrer des retours à la ligne
    sub titre {
    local ($/, *IN);
    open IN,"< $_[0]" or die "On cherche encore, ce fichier n'existe pas...\n";
    while(<IN>){
    	chomp;
    	if (/font-size: $_[1]\D\D\W\W.*;\W\W([^<]+)/){
    	print "$1\n";
    	}
    }
     
     
    close IN;
    }

  8. #8
    Membre averti
    Homme Profil pro
    Gérant infopsylon
    Inscrit en
    Juin 2010
    Messages
    215
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : Gérant infopsylon
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2010
    Messages : 215
    Points : 328
    Points
    328
    Par défaut
    Marlann,

    Franchement ton script ne peut pas fonctionner, il y a trop d'erreur de codage.

    Sur la base de ce que tu as commencé à écrire je t'ai fait une petite mouture qui te donne quel est ton max et dans quel fichier.

    A toi qd même d'écrire la suite.

    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
     
    #!/usr/bin/perl -w
     
    use strict;
     
    my $max=0;
    my $max_file_name="";
    my $SOURCE = "./www/*.htm";
    my @listfic;
    foreach (glob ($SOURCE)) 
    {
        push(@listfic, $_);
    }
     
    foreach my $entree (@listfic) 
    {
        print "$entree\n";
        my $tmp=max($entree);
        if ($tmp > $max)
        {
    	$max=$tmp;
    	$max_file_name=$entree;
        }
    }
     
    print "MAX trouvé : $max, dans le fichier $max_file_name\n";
     
    #identifier les font-size
    sub max 
    {
        my ($file)=@_;
        my $rd_val=0;
        my $max_in_file=0;
        open IN,"<$file" or die "Impossible d'ouvrir le fichier $file\n";
        while(<IN>) 
        {
    	chomp($_); 
    	if ($_ =~ /font-size:\ [0-9]+px/)
    	{
    	    ($rd_val)=($_ =~ /font-size:\ ([0-9]+)px/);
    	    if ( $rd_val > $max_in_file )
    	    {
    		$max_in_file=$rd_val;
    	    }
    	}
        }
        close IN;
        return $max_in_file;
    }
    Bonne continuation.


    J'aurai trop de difficultés à t'expliquer toutes tes erreurs, mais si tu as des questions sur ce que je viens de t'envoyer, n'hésites pas.

    @+
    Lilian.

  9. #9
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Citation Envoyé par lilian_h Voir le message
    Marlann,

    Franchement ton script ne peut pas fonctionner, il y a trop d'erreur de codage.

    Bon bin il ne me reste plus qu'à tenter plutôt le tricot et arrêter le Perl...

    Juste avant, je vais quand même essayer de finir ça. En tous cas, merci beaucoup à tous deux pour vos conseils et indications. Je vais déjà réécrire le tout en faisant passer en arguments mes variables, comme vous le faites.
    Pas sûr que ce soit le problème, mais si ça m'évite de faire des tas d'erreurs...

    Lilian, si je lis bien ton script, il s'agit de calculer le max absolu de tous les fichiers ; en me relisant je m'aperçois que je suis resté un peu trop elliptique, parce que ce que je cherche à faire, c'est isoler un max pour chacun de mes fichiers (l'objectif final étant d'isoler le titre de chacun d'entre eux et d'obtenir chacun de ces titres en sortie, une sorte de démarche bibliographique).

    Hop, je re-bûche tout ça!

    @ bientôt (avec un badge "résolu" j'espère),
    Marlann

  10. #10
    Membre averti
    Homme Profil pro
    Gérant infopsylon
    Inscrit en
    Juin 2010
    Messages
    215
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : Gérant infopsylon
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2010
    Messages : 215
    Points : 328
    Points
    328
    Par défaut
    Marlann,

    Ton problème n'est pas qu'un problème de variables globales vs. locales.

    Dans la fonction max(), d'où sors tu ton expression regulière ? Pourquoi avoir mis $max à l'intérieur ?

    Ici (ref à ton premier post):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if (/font-size[\D]*${max}[^>]+>([^<]+)/) {
    	print "$1\n";
    	}
    	if ($1>$max){
    	$max=$1;
    	}
    $max vaut 0 au premier passage, donc tu cherche font-size[\D]*0[^>..., je ne crois pas que ce que tu as écrit réponde vraiment à tes attentes...
    En plus, comme tu cherche un font-site de la taille de ton max (ici 0) même si miraculeusement tu en obtenais une, comment serait-il possible qu'elle soit supérieure à $max ? Ton if c'est comme si tu écrivais :
    if( $max > $max) ...

    De plus, l'usage de ton $1, ne fait pas référence à la valeur de la size de la font..., mais à ca [^<]+), donc le texte qui se trouve après la balise font-size

    En fait plus je lis, plus je me fais de noeud au cerveau ... mdr

    N'aurais-tu tout simplement pas mélanger le rôle de tes fonctions ?
    J'ai l'impression que les deux tendent à extraire le texte lié à un max ...


    Bon, bref.... En fait ton truc il marche pas, et c'est normal.

    Mais ne te décourage pas, c'est justement maintenant qu'il ne faut rien lâcher ! Le perl c'est facile, la complexité vient des concepts.

    @+
    Bon courage,
    Lilian.

  11. #11
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Mmmmh... Se pourrait-il que...
    Argh!
    Mais oui!

    Hé bien donc, mon problème insoluble est que je suis une grosse patate et qu'une erreur de copier-coller s'est donc glissée dans mon script quand j'ai voulu introduire le glob.

    Je ne vais même pas me mettre au tricot, je vais tout juste me coucher en rond et pleurer sur ma propre bêtise, une semaine de retard pour ça...

    Bref, merci encore (et mes excuses, du coup) à mes interlocuteurs et à leurs conseils avisés (et notamment à l'oeil d'aigle de lilian) ; je laisse le code ci-dessous, qui fonctionne donc très bien (même s'il est moche et mal ficelé).

    @ plus,
    Marlann

    Code perl : 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
     
    $SOURCE ="C:/pouet/tsoin/atraiter/*.htm";
    $max=0;
     
    #lire et stocker le nom des fichiers 
     foreach (glob ($SOURCE)) {
     push(@listfic, $_);
    }
     
    #pour chaque fichier retrouvé, lancer l'exécution des subroutines
    foreach $entree (@listfic) {
    print "$entree\n";
    max();
    titre();
    }
     
    #identifier les font-size
    sub max {
    open IN,"< $entree" or die "On cherche encore, ce fichier n'existe po...\n";
    while(<IN>) {
       chomp; 
       if (/font-size[\D]*(\d\d|\d\.\d)/) {
    	print "$1\n";
    	}
    	if ($1>$max){
    	$max=$1;
    	}
    }
    print "max $max\n";
    close IN;
    }
     
    #extraire le titre, avec un peu de slurping pour ne pas s'encombrer des retours à la ligne
    sub titre {
    local ($/, *IN);
    open IN,"< $entree" or die "On cherche encore, ce fichier n'existe pas...\n";
    print "$entree\n";
    print "$max\n";
    while(<IN>){
    	chomp;
    	if (/font-size[\D]*${max}[^>]+>([^<]+)/){
    	print "$1\n";
    	}
    }
    close IN;
    }

  12. #12
    Membre averti
    Homme Profil pro
    Gérant infopsylon
    Inscrit en
    Juin 2010
    Messages
    215
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations professionnelles :
    Activité : Gérant infopsylon
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2010
    Messages : 215
    Points : 328
    Points
    328
    Par défaut
    Eyh !

    Et oui une erreur de copier-coller peut expliquer pas mal de chose !
    Content d'avoir pu t'aider.

    Je sais que je suis chiant, mais il me semble qd même que la veleur exprimer après font-size, peut prendre à ma connaissance au moins deux unités différentes : px et em...
    Petite question donc, comment vas-tu gérer quel est réellement le taille maxi, je n'ai rien vu dans ton script permettant de faire une conversion em->px ?

    @+
    Lilian.

  13. #13
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Hé bien en l'espèce, je n'ai que du px en entrée, ce sont des htm qui sont eux-mêmes générés à la chaîne et donc normalisés ; pas de risques donc de comparer du em et du px...

    @+
    Marlann

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

Discussions similaires

  1. [AC-2002] Boucle pour importer et traiter des fichiers excel dans un dossier
    Par Tinien dans le forum VBA Access
    Réponses: 9
    Dernier message: 02/06/2010, 12h59
  2. Traiter des fichiers un a un
    Par Paloma dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 02/11/2006, 11h47
  3. Réponses: 7
    Dernier message: 15/06/2006, 18h36
  4. [Eclipse 2.1] des fichiers qui sautent dans WEB-INF/classes
    Par iubito dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 04/10/2004, 17h07
  5. [Fichiers] Enregistrer/Déplacer dans un répertoire
    Par babyboy dans le forum Entrée/Sortie
    Réponses: 19
    Dernier message: 12/05/2004, 15h33

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