[Perl] Comparaison de caractères

Résolu
khaz Messages postés 26 Statut Membre -  
lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   -
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

  1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    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)
    0
  2. khaz Messages postés 26 Statut Membre 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 ?
    0
  3. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    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 

    0
  4. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    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
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. khaz Messages postés 26 Statut Membre 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à.
    0
  7. sipi
     
    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
    0
  8. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    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


    0