[Perl] Comparaison de caractères

Résolu/Fermé
Signaler
Messages postés
26
Date d'inscription
lundi 29 mars 2004
Statut
Membre
Dernière intervention
29 mars 2008
-
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
-
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

Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 562
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)
Messages postés
26
Date d'inscription
lundi 29 mars 2004
Statut
Membre
Dernière intervention
29 mars 2008
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 ?
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 562
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 

Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 562
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
Messages postés
26
Date d'inscription
lundi 29 mars 2004
Statut
Membre
Dernière intervention
29 mars 2008
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à.
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
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 562
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