Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Aide | Shop Recherche
2324 connectés 

  FORUM HardWare.fr
  Programmation
  Perl

  [Perl] Comparaison de fichiers

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Perl] Comparaison de fichiers

n°2303200
web_olivie​r
R1 Powaaaaa
Posté le 11-07-2017 à 13:14:37  profilanswer
 

Bonjour,
 
J'ai besoin de comparer basiquement 2 fichiers XML.
 
Le principe est si une ligne du xml2 n'est pas dans le xml1 alors j'écris la ligne dans un fichier de résultat.
 
j'ai écris le code suivant :

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. my $xml1="full.xml";
  5. my $xml2="full2.xml";
  6. my $result="result.txt";
  7. # Ouverture des fichiers
  8. open (fXML1, $xml1) or die "$xml1 : $!";
  9. open (fXML2, $xml2) or die "$xml2 : $!";
  10. # Copie du contenu des fichiers dans un tableau
  11. my @lines1=<fXML1>;
  12. my @lines2=<fXML2>;
  13. # Fermeture des fichiers
  14. close (fXML1);
  15. close (fXML2);
  16. # Afficher la taille des tableaux
  17. print scalar(@lines1)."\n";
  18. print scalar(@lines2)."\n";
  19. #création du fichier résultat
  20. open (fResult,">$result" ) or die "$result : $!";
  21. foreach my $line2 (@lines2)
  22. {
  23. my $present=0;
  24. foreach my $line1 (@lines1)
  25. {
  26.  if ($line1 eq $line2)
  27.  {
  28.   $present=1;
  29.   next;
  30.  }
  31. }
  32. if ($present==0)
  33. {
  34.  print fResult $line2;
  35. }
  36. }
  37. #fermeture du fichier résultat
  38. close (fResult);


 
Le problème c'est que mes XML font chacun plus de 300 000 lignes et c'est donc très long et gourmand en CPU.
Avez vous une piste pour optimiser ce genre de traitement  ?
 
Par avance merci.
 
:hello:

mood
Publicité
Posté le 11-07-2017 à 13:14:37  profilanswer
 

n°2303203
The_Kid
Call me Billy
Posté le 11-07-2017 à 14:03:42  profilanswer
 

300.000 * 300.000 itérations ca fait beaucoup.
 
A mon avis il faut que tu arrives à trier tes lignes en amont.
Peu etre en fonction de la balise qui commence ta ligne.
 
Tu fais une map contenant le nom de la balise suivie des lignes ou elle se trouve. Au lieu d'itérer sur l'ensemble tu compares sur un plus petit sous ensemble.
 
Après si t'as beaucoup de balises avec des noms différents, c'est la merde.
 

n°2303204
web_olivie​r
R1 Powaaaaa
Posté le 11-07-2017 à 14:15:01  profilanswer
 

Merci The_Kid :jap:
 
En fouillant un peu plus sur le net je suis tombé sur Array:Utils.
 
j'ai donc adapté ça :
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Array::Utils qw(:all);
  5. my $xml1="full.xml";
  6. my $xml2="full2.xml";
  7. my $result="result2.xml";
  8. # Ouverture des fichiers
  9. open (fXML1, $xml1) or die "$xml1 : $!";
  10. open (fXML2, $xml2) or die "$xml2 : $!";
  11. # Copie du contenu des fichiers dans un tableau
  12. my @lines1=<fXML1>;
  13. my @lines2=<fXML2>;
  14. # Fermeture des fichiers
  15. close (fXML1);
  16. close (fXML2);
  17. # Afficher la taille des tableaux
  18. print scalar(@lines1)."\n";
  19. print scalar(@lines2)."\n";
  20. #création du fichier résultat
  21. open (fResult,">$result" ) or die "$result : $!";
  22. # check if arrays contain same members
  23. if ( !array_diff(@lines1, @lines2) )
  24. {
  25. print "Les xml sont identiques";
  26. }
  27. # get items from array @lines1 that are not in array @lines2
  28. my @minus = array_minus( @lines2, @lines1 );
  29. print fResult @minus;
  30. #fermeture du fichier résultat
  31. close (fResult);


 
Je suis en train de regarder mais à priori ça fait le taf.


Message édité par web_olivier le 11-07-2017 à 14:15:41
n°2303240
gilou
Modérateur
Modzilla
Posté le 12-07-2017 à 00:50:21  profilanswer
 

Si c'est juste pour savoir quelles lignes de fichier2 ne sont pas dans fichier1 en se moquant de l'ordre des lignes,
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use autodie;
  5.  
  6. my ($xml1, $xml2, $result) =('full1.xml', 'full2.xml', 'result.xml');
  7. my %xml1_lines;
  8.  
  9. open(my $fh, '<', $xml1);
  10. while (<$fh> ) {
  11.    $xml1_lines{$_}++;
  12. }
  13. close($fh);
  14.  
  15. open($fh, '<', $xml2);
  16. open(my $gh, '>', $result);
  17. while (<$fh> ) {
  18.    unless ($xml1_lines{$_}) {
  19.        print $gh $_;
  20.    }
  21. }
  22. close($gh);
  23. close($fh);


Bon, c'est codé à vue, donc SGDG, j'ai pu faire des typos.
 
Si tu veux vraiment exploiter la structure xml des fichiers, il faudrait plutôt utiliser XML::Diff
 
A+,


Message édité par gilou le 12-07-2017 à 11:13:04

---------------
Samantha Fish Rulez!     --    Iyashikei Anime Forever!    --    In umbra igitur pugnabimus. --
n°2303781
web_olivie​r
R1 Powaaaaa
Posté le 24-07-2017 à 12:51:55  profilanswer
 

Merci beaucoup Gilou :)


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Perl

  [Perl] Comparaison de fichiers

 

Sujets relatifs
Boucle taille fichiers et lancementexpression régulière avec perl
bat sur une list de fichiers csv avec plusieurs valeurs[résolu]problème comparaison Php/MySql
optimisation script perlVBS Lister les fichiers d'un répertoire et sous repertoire
Comparaison de variables avec un pdf OCRisésscript perl pour remplacement des chiffre en mots
Création d'un Procédure pour la comparaison de deux tables[PERL/MySQL] Utilisation d'une variable dans la clause Where
Plus de sujets relatifs à : [Perl] Comparaison de fichiers



Copyright © 1997-2016 Hardware.fr SARL (Signaler un contenu illicite) / Groupe LDLC / Shop HFR