[Perl] Comparaison de caractères

Résolu
Bonjour à tous,

j'ai un problème avec un script perl. Enfin lors d'une comparaison entre 2 chaines de caracteres visiblement identique, celle ci sont considérées comme étant différentes.

Voici ma comparaison :
$Compar = $BO{$cli}{$mod} cmp $SGI{$cli}{$mod};
print " comparaison : $Compar $BO{$cli}{$mod} et $SGI{$cli}{$mod} pour \n";

son résultat :
comparaison : -1
Location de T3, centre ville face mer§piscine, tennis sur place,§golf, casino, thalasso et cinéma à proximité.
Location de T3, centre ville face mer§piscine, tennis sur place,§golf, casino, thalasso et cinéma à proximité.


Et comment elles sont remplies a partir d'un fichier :
while ($Lig = <Fic>)
{
chomp $Lig;
($cli, $mod, $lig1, $lig2, $lig3) = split(/§/, $Lig);
$cli += 0;
$mod += 0;
$BO{$cli}{$mod} = "$lig1§$lig2§$lig3";
}
[...]
while ($Lig = <Fic>)
{
chomp $Lig;
($cli, $mod, $lig1, $lig2, $lig3) = split(/§/, $Lig);
$cli += 0;
$mod += 0;
if (! $BO{$cli}{$mod})
{
print Sortie "$cli-$mod\n";
$SGIseul ++;
}
else
{
$SGI{$cli}{$mod} = "$lig1§$lig2§$lig3";
}
}
if ($SGIseul == 0)
{
print Sortie "Aucun\n";
}



Vous auriez une piste?
Une fonction permettant de mettre en évidence les différences entre 2 chaines de caractères ?

7 réponses

  • Votes
  • Date
  • Date décroissante
  1. Modérateur
    Salut,

    Vous auriez une piste?
    Si tu peux donner ton fichier sur cjoint.com je pourrais tester

    sinon tu peux faire une conversion des caractères en ASCII pour voir le caratère qui traine

    Regarde danc cet exemple.
    On a l'impression que les lignes sont identiques, en revanche quand je fais la conversion en ASCII je vois la différence (voir en gras)
    lami20j@debserv:~/trash$ cat fic.txt
    abcdef
    abcdef
    abcdef
    lami20j@debserv:~/trash$ perl -ne 's/(.)/ord($1)/egs;print "$_\n"' fic.txt
    97989910010110210
    9798991001011023210
    979899100101102910
    

    la deuxième ligne a un espace à la fin (ASCII 32)
    la 3ème une tabulation (ASCII 9)
    1. après la conversion en caractères ascii, il y'a effectivement un probleme en fin de ligne .

      [proexp@lrec11 samantha]$ perl -ne 's/(.)/ord($1)/egs;print "$_\n"' bopro3.csv
      48484851495057541674848485116776111999711610511111032100101328451443299101110116114101321181051081081013210297991013210910111416711210511599105110101443211610111011010511532115117114321121089799101441671031111081024432999711510511011144321161049710897115115111321011163299105110233109973222432112114111120105109105116233461310
      48484851495057541674848485016767111110103114232115443211523310910511097105114101115321161111171161013210839971101102331014616711210511599105110101443211610111011010511532115117114321121089799101461671031111081024432999711510511011144321161049710897115115111321011163299105110233109973222432112114111120105109105116233461310
      [proexp@lrec11 samantha]$ perl -ne 's/(.)/ord($1)/egs;print "$_\n"' sgipro3.csv
      484848514950575416748484850167671111101031142321154432115233109105110971051141011153211611111711610132108399711011023310146167112105115991051101014432116101110110105115321151171143211210897991014616710311110810244329997115105110111443211610497108971151151113210111632991051102331099732224321121141111201051091051162334610
      484848514950575416748484851167761119997116105111110321001013284514432991011101161141013211810510810810132102979910132109101114167112105115991051101014432116101110110105115321151171143211210897991014416710311110810244329997115105110111443211610497108971151151113210111632991051102331099732224321121141111201051091051162334610

      Pour mon premier fichier j'ai donc des retours chariots et des saut de lignes alors que dans le deuxieme, j'ai que les sauts de lignes.
      Par contre, je m'interroge sur le chomp à présent : quel caractère supprime t'il ? le retour chariot ou le saut de ligne ?
      Et du coup, comment faire pour que ma comparaison se fasse sans accroc malgré cette différence ?

      En executant la commande file sur mes fichiers j'obtiens ceci :
      bopro3.csv: UTF-8 Unicode text, with CRLF line terminators
      sgipro3.csv: UTF-8 Unicode text

      Vous sauriez quel format de fichier me permettrait d'homogénéiser le tout avec la commande iconv ?
      1. Modérateur
        Par contre, je m'interroge sur le chomp à présent : quel caractère supprime t'il ? le retour chariot ou le saut de ligne ?
        voici ce que fait chomp
        supprime toute fin de ligne correspondant à la valeur courante de $/ (connue aussi sous le nom de $INPUT_RECORD_SEPARATOR

        dans ton cas il s'agit d'un problème classique: ton fichier qui a les lignes qui se finissent avec 1310 sont des fichiers qui viennent depuis Windows

        tu peux faire s/\r//pour supprimer le RetourChariot (Carriage Return - code ASCII 13)

        essaie
        perl -ne 's/\r//;s/(.)/ord($1)/egs;print "$_\n"' bopro3.csv 
        perl -ne 's/(.)/ord($1)/egs;print "$_\n"' sgipro3.csv 

        1. Modérateur
          tu peux aussi ouvrir les fichier avec
          open FiC, "<:crlf", "fichier1.txt"
                 or die "E/S : $!\n";


          qui permet la conversion de CRLF en LF en lecture et de LF en CRLF en écriture
          1. Merci beaucoup pour ton aide qui m'aura permis de cibler la cause du problème: l'encodage de mes fichiers.
            En effet, comme je suis déjà amené à à convertir mes fichiers en entrée dans un certain encodage, je préfére trouver un encodage pertinent plutot que de modifier mon code.
            J'ouvre un autre sujet sur ce point là.
            1. Salut voila, je suis tomber sur ce post car je cherche à transformer mes caractère 10 en 1310 par une commande du genre:
              perl -ne 's/(.)/ord($1)/egs;print "$_\n"' monfichier.txt | sed 's/10/1310/g' | (((commande pour retourner en caractere normal soit inverse de perl -ne 's/(.)/ord($1)/egs;print "$_\n"' csup.txt))) > monfichier.txt

              ca pourrait beaucoup m'aider
              car j'ai une bonne petite quantité de fichier text à transcrire pour pouvoir les utiliser sur windows au boulot
              1. Modérateur
                Salut,

                Cas 1
                - fichier Unix (fin ligne \n) vers fichier Win (fin ligne \r\n)
                lami20j@debian:~$ cat -v fic1013.txt
                ligne1
                ligne2
                ligne3
                lami20j@debian:~$ perl -ne 's/(.)/ord($1)/seg;print "$_\n"' fic1013.txt
                1081051031101014910
                1081051031101015010
                1081051031101015110
                lami20j@debian:~$ perl -pi.orig -e 's/\n/\r\n/' fic1013.txt
                lami20j@debian:~$ cat -v fic1013.txt
                ligne1^M
                ligne2^M
                ligne3^M
                lami20j@debian:~$ perl -ne 's/(.)/ord($1)/seg;print "$_\n"' fic1013.txt
                108105103110101491310
                108105103110101501310
                108105103110101511310
                lami20j@debian:~$ cat -v fic1013.txt.orig
                ligne1
                ligne2
                ligne3
                lami20j@debian:~$ perl -ne 's/(.)/ord($1)/seg;print "$_\n"' fic1013.txt.orig
                1081051031101014910
                1081051031101015010
                1081051031101015110


                Cas 2 - fichier Win (fin ligne \r\n) vers fichier Unix (fin ligne \n)
                lami20j@debian:~$ perl -pi.orig -e 's/\r//' fic1013.txt
                lami20j@debian:~$ cat -v fic1013.txt
                ligne1
                ligne2
                ligne3
                lami20j@debian:~$ perl -ne 's/(.)/ord($1)/seg;print "$_\n"' fic1013.txt
                1081051031101014910
                1081051031101015010
                1081051031101015110
                lami20j@debian:~$ cat -v fic1013.txt.orig
                ligne1^M
                ligne2^M
                ligne3^M
                lami20j@debian:~$ perl -ne 's/(.)/ord($1)/seg;print "$_\n"' fic1013.txt.orig
                108105103110101491310
                108105103110101501310
                108105103110101511310
                lami20j@debian:~$


                Toujours en Perl il y a aussi la possibilité d'utiliser la couche E/S :ctrlf

                open FILE ,"<:crlf", "fichier.txt"; # ouvrir le fichier en lecture, effectue les substitutions de CRLF
                                                    #en saute de ligne et vice versa en fonction de OS utilisé 


                Une autre alternative c'est d'utiliser les commandes dos2unix et unix2dos.
                Pour la distribution Debian Etch il faut installer le paquet tofrodos :
                aptitude install tofrodos