Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Cocktail: Fichier, Grep/Regexp, Hash... :-)

5 réponses
Avatar
fun.x
Bonjour,

Voila, g un fichier source.txt et un fichier target.txt. Source
contient une liste de chaines de caracteres a rechercher dans
target.txt.
Pour cela, je memorise les strings de Source dans une table de hash.
Ensuite, j'ouvre target.txt et j'y recherche le nombre d'occurences de
chaque clef de la table. Si la clef apparait dans target.txt, j'efface
la clef de la table.

Ca a l'air simple, mais g du mal avec grep essentielement, puisque il
retourne toujours 0...

Je vous copie tout le code pour plus de clarte.
De plus, tous les conseils d'optimisations, sont les bienvenus pour un
debutant comme moi ! :-)

D'avance merci.
MA

-------------------------------------------------------------------
CODE:
#!/usr/bin/perl -w
#!C:\Perl\bin\perl.exe -w

use strict;
use warnings;

my $argc=@ARGV;
if ($argc != 2) {
printf ("USAGE: $0 <SOURCE> <CHECKED>\n");
exit;
}

my $source = $ARGV[0];
my $checked = $ARGV[1];
my %hash = ();

#Get list of tags into a hash table (values/occurences initialized to
0)
open(LIST, $source) or die "Error while opening source file ($source):
$!\n";
while(<LIST>) {
chomp;
next if (length($_) == 0);
$hash{$_} = 0;
}
close LIST;

{
my $nb = keys(%hash);
my @tags = keys(%hash);
printf "\n";
printf "Initialization done - Nb of entries: $nb\n";
printf "Keys: @tags\n";
printf "\n-----------------------------------\n\n";
}

#Perform check on the target file
open MYFILE, $checked or die "Error while opening checked file
($checked): $!\n";

my @list = 1 while <MYFILE>;
my $count;

foreach my $i (keys(%hash)) {
$count = grep(/$i/i,@list);
printf "Found $count occurences for \'$i\'\n";
delete($hash{$i}) if ($count > 0);
}

{
my $nb = keys(%hash);
my @tags = keys(%hash);
printf "\n-----------------------------------\n\n";
printf "Operation done - Nb of entries: $nb\n";
printf "Keys: @tags\n";
}
close MYFILE;
-------------------------------------------------------------------
source.txt:
aaa
bbb
ccc

-------------------------------------------------------------------
target.txt:
lkmdclkmdc.aaa s
ser aaaa
ded.ccc+ddd

-------------------------------------------------------------------
Resultat:
D:\Others\perl>perl -w test2.pl source.txt target.txt

Initialization done - Nb of entries: 3
Keys: bbb aaa ccc

-----------------------------------

found 0 occurences for 'bbb'
found 0 occurences for 'aaa'
found 0 occurences for 'ccc'

-----------------------------------

Operation done - Nb of entries: 3
Keys: bbb aaa ccc

-------------------------------------------------------------------

5 réponses

Avatar
fun.x
Autant pour moi...
Un vieux copie-colle tout con est a l'origine du bug...

my @list = 1 while <MYFILE>;


doit etre remplace par

my @list = <MYFILE>;

Par contre, niveau optimisations, je suis sur que je suis pas au top...
Et c'est un peu pour ca que je me suis mis au Perl, alors d'avance
merci pour vos conseils :-)

MA

PS: Desole pour la longueur du precedent message, mais ca sera toujours
utile aux autres newbies comme moi.

Avatar
Jacques Caron
On 30 May 2005 22:55:12 -0700, fun.x wrote:

Par contre, niveau optimisations, je suis sur que je suis pas au top...


Pourquoi faire une boucle sur le fichier destination pour chaque chaîne à
chercher? Je ferais l'inverse, sinon le hash n'est pas spécialement utile,
une liste suffirait.

Jacques.
--
Interactive Media Factory
Création, développement et hébergement
de services interactifs: SMS, SMS+, Audiotel...
http://www.imfeurope.com/

Avatar
fun.x
Pourquoi faire une boucle sur le fichier destination pour chaque chaîne à
chercher? Je ferais l'inverse, sinon le hash n'est pas spécialement uti le,
une liste suffirait.


Desole, j'ai pas saisi l'idee...
Pour info, une prochaine evolution du script recherchera les chaines
dans n fichiers ... d'ou la boucle sur le fichier avec une liste de
chaines destinee a reduire petit a petit.

Avatar
Jacques Caron
Salut,

On 31 May 2005 00:50:42 -0700, fun.x wrote:

Desole, j'ai pas saisi l'idee...


while (<FICHIER>)
{
chop;
if (defined $hash{$_})
{
# faire whatever tu as envie de faire
delete $hash{$_};
}
}

Comme la recherche dans le hash est optimisée, ça va plus vite comme ça
que dans l'autre sens. En tout cas ça devrait :-)

Jacques.
--
Interactive Media Factory
Création, développement et hébergement
de services interactifs: SMS, SMS+, Audiotel...
http://www.imfeurope.com/

Avatar
Marc
Hello,

while (<FICHIER>)
{
chop;
if (defined $hash{$_})
{
# faire whatever tu as envie de faire
delete $hash{$_};
}

}



Petit newbie que je suis ... je suis pas d'accord :-)
Je ne vois pas comment en parcourant le fichier ligne par ligne je peux
arriver a faire ce qui est dans mon script ...
Comme tu peux le voir dans le fichier target.txt du premier post, il
n'est +clairement+ pas dit que le fichier que je controle (FICHIER pour
toi) a ses lignes composees uniquement des clefs de la table de hash...
Celle ci peut etre noyee au milieu d'autres saletees :-)

Donc, le test if (defined $hash{$_}) sera forcement toujours faux
puisque $_ contient toute la ligneet psa uniquement la clef.

Ou peut-etre existe-t-il un truc que je connais pas encore en Perl ?