On peut travailler avec de tables de hachages (hash) et tableau quand il s'agit de petits fichiers
En revanche quand on traite des gros fichiers il faut penser à la mémoire disponible
Voilà un exemple
J'ai 2 fichiers dont un est l'autre à l'envers. Ce qui veut dire que les fichiers ne sont pas identiques.
Dans le 1er script je n'utilise pas de tableaux, en revanche j'utilise de handles de fichiers dans lequels je vais écrire les différences si c'est le cas sinon je vais afficher un messsage
Le script
$ cat comparefic2.pl
#!/usr/bin/perl
#
use strict;use warnings;
# ouverture de fichiers en lecture
open F_LIRE1,"fic1" or die "E/S : $!\n";
open F_LIRE2,"fic2" or die "E/S : $!\n";
open F_A,">>fic1diff" or die "E/S : $!\n";
open F_B,">>fic2diff" or die "E/S : $!\n";
# $f1 lit les ligne dans le 1er fichier
# $f2 dans le 2ème
my ($f1,$f2);
my $i=0;
# lecture des fichiers ligne par ligne
# avant de paser à la ligne suivante on compare les lignes
# si les lignes ne sont pas identiques
# j'écris dans les fichiers correspondants
while ( defined($f1=<F_LIRE1>) and defined($f2=<F_LIRE2>) ){
chomp($f1); # suppression de caractère de fin de ligne
chomp($f2);
( (print F_A "$f1\n"),
(print F_B "$f2\n"),
++$i )unless $f1 eq $f2;
}
if ($i == 0){
print "Les fichiers sont identiques.\n";
unlink <fic*diff>;
}else{
print "Les fichiers ne sont pas identiques.\n";
print "-fichier fic1diff :les lignes se trouvant que dans fic1\n";
print "-fichier fic2diff :les lignes se trouvant que dans fic2\n";
}
__END__
Dans le 2ème script je sauvegarde les differences dans 2 tableaux.
Le script 2
#!/usr/bin/perl
#
use strict;use warnings;
# ouverture de fichiers en lecture
open F_LIRE1,"fic1" or die "E/S : $!\n";
open F_LIRE2,"fic2" or die "E/S : $!\n";
# $f1 lit les ligne dans le 1er fichier
# $f2 dans le 2ème
my ($f1,$f2);
# @A - tableau qui contiendra les lignes existantes que dans le 1er fichier
# @B - que dans le 2ème fichier
my (@A,@B);
# lecture des fichiers ligne par ligne
# avant de paser à la ligne suivante on compare les lignes
# si les lignes ne sont pas identiques
# $f1 est ajouté à @A et $f2 est ajouté à @B
while ( defined($f1=<F_LIRE1>) and defined($f2=<F_LIRE2>) ){
chomp($f1); # suppression de caractère de fin de ligne
chomp($f2);
( (push @A,$f1),
(push @B,$f2) ) unless $f1 eq $f2;
}
if ((@A+@B) ==0){ # si la somme des elements de @A et @B est 0
print "Les fichiers sont identiques.\n";
}else{
print "Les fichiers ne sont pas identiques\n";
}
__END__
Et voilà l'exécution (à étudier avec attention :-))
Execution de 1er script (donc sans tableaux)
lami20j@debian:~/trash$ time perl comparefic2.pl
Les fichiers ne sont pas identiques.
-fichier fic1diff :les lignes se trouvant que dans fic1
-fichier fic2diff :les lignes se trouvant que dans fic2
real 0m13.764s
user 0m6.664s
sys 0m1.140s
Execution de 2ème script (j'ai du l'arrêter avec CTRL+C)
lami20j@debian:~/trash$ time perl comparefic.pl
Les fichiers ne sont pas identiques
real 3m42.216s
user 0m7.760s
sys 0m2.036s
Et voilà la taille et les nombre de lignes de chaque fichier
lami20j@debian:~/trash$ du -h fic1
54M fic1
lami20j@debian:~/trash$ du -h fic2
54M fic2
lami20j@debian:~/trash$ du -h fic1diff
53M fic1diff
lami20j@debian:~/trash$ du -h fic2diff
53M fic2diff
lami20j@debian:~/trash$ cat fic1 | wc -l
2184192
lami20j@debian:~/trash$ cat fic2 | wc -l
2184192
lami20j@debian:~/trash$ cat fic1diff | wc -l
2101248
lami20j@debian:~/trash$ cat fic2diff | wc -l
2101248
A toi de voir
lami20j