Script 4 : parcours de l'arborescence sans doublon
Voici le nouveau programme qui parcourt toute l'arborescence et qui enlève les doublons :
Programme :
#/usr/bin/perl
<<DOC;
Votre Nom : Marion ICHE et Sophie PAPAZOGLOU
JANVIER 2008
usage : perl parcours-arborescence-fichiers repertoire-a-parcourir
Le programme prend en entrée le nom du répertoire contenant les fichiers
à traiter
Le programme construit en sortie un fichier structuré contenant sur chaque
ligne le nom du fichier et le résultat du filtrage :
<FICHIER><NOM>du fichier</NOM></FICHIER><CONTENU>du filtrage</CONTENU></FICHIER>
DOC
#-----------------------------------------------------------
my $rep="$ARGV[0]";
# on s'assure que le nom du répertoire ne se termine pas par un "/" si ça se termine par / on remplace par rien
$rep=~ s/[\/]$//;
# on initialise une variable contenant le flux de sortie
my $DUMPFULL1="";
my %tableaudestextes=(); # pour mémoriser ce qu'on a déjà imprimé, pour éviter les doublons
#----------------------------------------
my $output1="SORTIE.xml";
if (!open (FILEOUT,">$output1")) { die "Pb a l'ouverture du fichier $output1"};
#----------------------------------------
&parcoursarborescencefichiers($rep); # on appelle le sous programme
#----------------------------------------
print FILEOUT ".$DUMPFULL1.";
close(FILEOUT);
exit;
#----------------------------------------------
sub parcoursarborescencefichiers { # on entre dans le sous programme
my $path = shift(@_); # on met dans la variable $path le contenu de la variable mise en argument
opendir(DIR, $path) or die "can't open $path: $!\n"; # opendir : ouvre un rep - si on arrive pas : le pgm s'arrete et on envoie un message d'erreur
my @files = readdir(DIR); # on lit le contenu du répertoire et on renvoie une liste qu'on stocke dans @files
closedir(DIR);
foreach my $file (@files) { # pour chaque ressource dans @files,on crèe $files
next if $file =~ /^\.\.?$/; # on passe au suivant si on trouve . ou .. car on risque une boicle infinie
$file = $path."/".$file; # on réécrit tout le chemin du fichier - le point permet la concaténation
if (-d $file) { # on entre dans cette boucle si il y a dans $file un répertoire (-d vérifie que l'argument est un répertoire)
&parcoursarborescencefichiers($file); #recurse!
}
if (-f $file) { # on entre dans cette boucle si il y a dans $file un fichier (-f vérifie que l'argument est un fichier)
if ($file=~/.xml/){ # parcourt toute l'arborescence pour ne garder que les fichiers .xml
open(FILEIN,$file); # on ouvre le fichier qu'on va lire
$i=1; # compteur
printf "$file\n"; # on voit si ça travaille
while ($ligne = <FILEIN>){ # tant qu'il y a qqch à lire, on rentre dans la boucle
if (($ligne!~/Retrouvez *l.*ensemble *des/) && ($ligne!~/Lisez *l.*int.*gralit.* *de *l.*article *pour *plus *d.*information./) && ($ligne!~/Toute *l.*actualit.* *au *moment *de *la *connexion/)) {
if ($ligne=~/<description>([^<]+)<\/description>/) { # si on trouve ce motif, on entre dans la boucle
my $propre=$1;# on prend le motif et on le met dans $propre
$propre=~s/&#39;/\'/g;# nettoie
$propre=~s/&#34;/\"/g;# nettoie
$propre=~s/é/é/g;# nettoie
$propre=~s/ê/ê/g;# nettoie
if (exists($tableaudestextes{$propre})) { # on mémorise $propre
$tableaudestextes{$propre}++; # on incrémente la valeur de $propre FACULTATIF (pour faire plaisir à M. FLEURY)
} # mais on ne la réimprime pas afin de supprimer les doublons si il existe déjà
else { # on entre dans cette boucle si il n'existe pas encore
$DUMPFULL1.="$propre\n"; # on concatène le contenu de $propre obtenu dans chaque boucle
$i++; # on incrémente le compteur
$tableaudestextes{$propre}++; # on incrémente pour dire qu'on a déjà rencontré ce texte pour qu'après si on le retrouve on ne réimprime pas la même séquence
}
} # fin de if
} # fin de if
} # fin de while
close(FILEIN); # on ferme le fichier en lecture
}
}
}
}
#----------------------------------------------
Explications :
Dans ce programme, on parcourt toute l'arborescence et on ne garde que les fichiers XML. On pourrait également choisir de ne garder que certains fichiers xml en les sélectionnant pas leur nom.
La ligne :
if (($ligne!~/Retrouvez *l.*ensemble *des/) && ($ligne!~/Lisez *l.*int.*gralit.* *de *l.*article *pour *plus *d.*information./) && ($ligne!~/Toute *l.*actualit.* *au *moment *de *la *connexion/)) {
permet de dire qu'on ne veut pas prendre en considération 3 phrases qui revenaient trop souvent. Il est important de mettres de && au lieu des ||, comme dans la version précédente, car si on ne met pas des &&, le programme s'attend à trouver les 3 phrases sur la même ligne, ce qui n'est pas possible. Les .* permettent d'éviter des problèmes liés aux accents. En effet, comme cette ligne intervient avant le nettoyage, il est possible qu'une ligne contienne un accent mal codé. On trouve aussi des accents entre les espaces, nous étions à ce moment là à la recherche d'un éventuel espace trop long !
Pour éliminer les doublons, on crèe un tableau de hachage : my %tableaudestextes=(); qui va contenir toutes les phrases écrites. Plus loin, les boucles 'if' et 'else' permettent de n'écrire en sortie que les phrases qui ne sont pas encore dans le tableau de hachage, c'est à dire toutes les phrases qui n'ont pas encore été écrites.
Enfin, on remarquera que toutes les balises XML ont été supprimées car on a besoin d'avoir un fichier en .txt en sortie et non en .xml
Sortie :
Voici le début de la sortie obtenue quand on lance ce programme sur le fichier 2008 qui ne contient que le mois de janvier :
.Un document confidentiel, que s'est procuré "Le Monde", trace les contours du désastre entraîné par le scrutin du 27 décembre, qui vient de plonger le Kenya dans une vague de violences.
La guerre pour l'investiture républicaine dans l'Iowa, dont le caucus du 3 janvier est capital, fait rage entre les deux hommes. M. Huckabee, qui a effectué une percée inattendue, est en tête selon les derniers sondages.
Pour aider ceux qui veulent renoncer au tabac, pharmaciens et médecins proposent timbres cutanés et inhalateurs. Efficacité comparée des différents traitements, avis des spécialistes... et méthodes alternatives.
Les chercheurs ont "sauté" la mutation génétique responsable de cette grave maladie et provoqué la production de
Programme :
#/usr/bin/perl
<<DOC;
Votre Nom : Marion ICHE et Sophie PAPAZOGLOU
JANVIER 2008
usage : perl parcours-arborescence-fichiers repertoire-a-parcourir
Le programme prend en entrée le nom du répertoire contenant les fichiers
à traiter
Le programme construit en sortie un fichier structuré contenant sur chaque
ligne le nom du fichier et le résultat du filtrage :
<FICHIER><NOM>du fichier</NOM></FICHIER><CONTENU>du filtrage</CONTENU></FICHIER>
DOC
#-----------------------------------------------------------
my $rep="$ARGV[0]";
# on s'assure que le nom du répertoire ne se termine pas par un "/" si ça se termine par / on remplace par rien
$rep=~ s/[\/]$//;
# on initialise une variable contenant le flux de sortie
my $DUMPFULL1="";
my %tableaudestextes=(); # pour mémoriser ce qu'on a déjà imprimé, pour éviter les doublons
#----------------------------------------
my $output1="SORTIE.xml";
if (!open (FILEOUT,">$output1")) { die "Pb a l'ouverture du fichier $output1"};
#----------------------------------------
&parcoursarborescencefichiers($rep); # on appelle le sous programme
#----------------------------------------
print FILEOUT ".$DUMPFULL1.";
close(FILEOUT);
exit;
#----------------------------------------------
sub parcoursarborescencefichiers { # on entre dans le sous programme
my $path = shift(@_); # on met dans la variable $path le contenu de la variable mise en argument
opendir(DIR, $path) or die "can't open $path: $!\n"; # opendir : ouvre un rep - si on arrive pas : le pgm s'arrete et on envoie un message d'erreur
my @files = readdir(DIR); # on lit le contenu du répertoire et on renvoie une liste qu'on stocke dans @files
closedir(DIR);
foreach my $file (@files) { # pour chaque ressource dans @files,on crèe $files
next if $file =~ /^\.\.?$/; # on passe au suivant si on trouve . ou .. car on risque une boicle infinie
$file = $path."/".$file; # on réécrit tout le chemin du fichier - le point permet la concaténation
if (-d $file) { # on entre dans cette boucle si il y a dans $file un répertoire (-d vérifie que l'argument est un répertoire)
&parcoursarborescencefichiers($file); #recurse!
}
if (-f $file) { # on entre dans cette boucle si il y a dans $file un fichier (-f vérifie que l'argument est un fichier)
if ($file=~/.xml/){ # parcourt toute l'arborescence pour ne garder que les fichiers .xml
open(FILEIN,$file); # on ouvre le fichier qu'on va lire
$i=1; # compteur
printf "$file\n"; # on voit si ça travaille
while ($ligne = <FILEIN>){ # tant qu'il y a qqch à lire, on rentre dans la boucle
if (($ligne!~/Retrouvez *l.*ensemble *des/) && ($ligne!~/Lisez *l.*int.*gralit.* *de *l.*article *pour *plus *d.*information./) && ($ligne!~/Toute *l.*actualit.* *au *moment *de *la *connexion/)) {
if ($ligne=~/<description>([^<]+)<\/description>/) { # si on trouve ce motif, on entre dans la boucle
my $propre=$1;# on prend le motif et on le met dans $propre
$propre=~s/&#39;/\'/g;# nettoie
$propre=~s/&#34;/\"/g;# nettoie
$propre=~s/é/é/g;# nettoie
$propre=~s/ê/ê/g;# nettoie
if (exists($tableaudestextes{$propre})) { # on mémorise $propre
$tableaudestextes{$propre}++; # on incrémente la valeur de $propre FACULTATIF (pour faire plaisir à M. FLEURY)
} # mais on ne la réimprime pas afin de supprimer les doublons si il existe déjà
else { # on entre dans cette boucle si il n'existe pas encore
$DUMPFULL1.="$propre\n"; # on concatène le contenu de $propre obtenu dans chaque boucle
$i++; # on incrémente le compteur
$tableaudestextes{$propre}++; # on incrémente pour dire qu'on a déjà rencontré ce texte pour qu'après si on le retrouve on ne réimprime pas la même séquence
}
} # fin de if
} # fin de if
} # fin de while
close(FILEIN); # on ferme le fichier en lecture
}
}
}
}
#----------------------------------------------
Explications :
Dans ce programme, on parcourt toute l'arborescence et on ne garde que les fichiers XML. On pourrait également choisir de ne garder que certains fichiers xml en les sélectionnant pas leur nom.
La ligne :
if (($ligne!~/Retrouvez *l.*ensemble *des/) && ($ligne!~/Lisez *l.*int.*gralit.* *de *l.*article *pour *plus *d.*information./) && ($ligne!~/Toute *l.*actualit.* *au *moment *de *la *connexion/)) {
permet de dire qu'on ne veut pas prendre en considération 3 phrases qui revenaient trop souvent. Il est important de mettres de && au lieu des ||, comme dans la version précédente, car si on ne met pas des &&, le programme s'attend à trouver les 3 phrases sur la même ligne, ce qui n'est pas possible. Les .* permettent d'éviter des problèmes liés aux accents. En effet, comme cette ligne intervient avant le nettoyage, il est possible qu'une ligne contienne un accent mal codé. On trouve aussi des accents entre les espaces, nous étions à ce moment là à la recherche d'un éventuel espace trop long !
Pour éliminer les doublons, on crèe un tableau de hachage : my %tableaudestextes=(); qui va contenir toutes les phrases écrites. Plus loin, les boucles 'if' et 'else' permettent de n'écrire en sortie que les phrases qui ne sont pas encore dans le tableau de hachage, c'est à dire toutes les phrases qui n'ont pas encore été écrites.
Enfin, on remarquera que toutes les balises XML ont été supprimées car on a besoin d'avoir un fichier en .txt en sortie et non en .xml
Sortie :
Voici le début de la sortie obtenue quand on lance ce programme sur le fichier 2008 qui ne contient que le mois de janvier :
.Un document confidentiel, que s'est procuré "Le Monde", trace les contours du désastre entraîné par le scrutin du 27 décembre, qui vient de plonger le Kenya dans une vague de violences.
La guerre pour l'investiture républicaine dans l'Iowa, dont le caucus du 3 janvier est capital, fait rage entre les deux hommes. M. Huckabee, qui a effectué une percée inattendue, est en tête selon les derniers sondages.
Pour aider ceux qui veulent renoncer au tabac, pharmaciens et médecins proposent timbres cutanés et inhalateurs. Efficacité comparée des différents traitements, avis des spécialistes... et méthodes alternatives.
Les chercheurs ont "sauté" la mutation génétique responsable de cette grave maladie et provoqué la production de
Publicité