[PERL] probleme avec foreach et l'ascii 10

probleme avec foreach et l'ascii 10 [PERL] - Perl - Programmation

Marsh Posté le 16-04-2008 à 14:24:29    

Bonjour a tous
 
Je sollicite votre aide pour un problème qui doit etre tout bete... enfin pas pour moi (sinon ce post ne serait pas là einh :) )
 
J'explique :
Je fais un bel appel systeme bien gras avec la  fonction "qx" sur une BDD avec ODBC... (je vous passe les details du "pourquoi je ne peux pas le faire avec DBI" )
 
En gros:

Code :
  1. @resultat = qx{echo "select id, desc from MaTable" |isql BDD_ODBC user mdp};


 
Je traite les resultats un a un avec un foreach:

Code :
  1. 1 | blablabla
  2. 2 | plop plop
  3. ...
  4. xx | aaaaaaaaaaaa


Code :
  1. foreach (@resultat)
  2. {
  3. ...
  4. }


 
Seulement le hic, c'est que des petits malins on mis des code ascii 10 (Line Feed, saut de ligne) dans leur desc (pour faire plus jolie :s)
et donc pour une ligne du genre :  

Code :
  1. x | Description : {10} blablabla {10} azazza


foreach comprend

Code :
  1. x | Description  :
  2. blablabla
  3. azazza


 
donc 3 tours de boucle au lieu de 1 seul :/
 
Il y a un moyen de parade ?  
 
Merci a tous
Et bonne journée


Message édité par 3xc4l18ur le 16-04-2008 à 14:30:06
Reply

Marsh Posté le 16-04-2008 à 14:24:29   

Reply

Marsh Posté le 16-04-2008 à 15:08:10    

Une petite ligne de test

Code :
  1. foreach (("aaa","bbb\nccc","ddd" )) {print "-->$_<--\n"};


Montre que le probleme n'est pas au niveau du foreach, mais du qx, qui par défaut, considère les \n comme des record separator.  

Citation :

qx/STRING/  
`STRING`  
A string which is (possibly) interpolated and then executed as a system command with /bin/sh or its equivalent. Shell wildcards, pipes, and redirections will be honored. The collected standard output of the command is returned; standard error is unaffected. In scalar context, it comes back as a single (potentially multi-line) string, or undef if the command failed. In list context, returns a list of lines (however you've defined lines with $/ or $INPUT_RECORD_SEPARATOR), or an empty list if the command failed.


Il va falloir jouer avec la valeur de $/ pour modifier cela. S'il y a un caractere separateur de record dans tes données, il faut positionner $/ a cette valeur (voire chaine).
Si tes records ont une taille maximale, tu peux peut etre utiliser la technique "$/ = \32768; # or \"32768", or \$var_containing_32768" explicitée dans la doc perl.

Citation :

input_record_separator HANDLE EXPR
 
$INPUT_RECORD_SEPARATOR
 
$RS
 
$/
 
The input record separator, newline by default. This influences Perl's idea of what a ``line'' is. Works like awk's RS variable, including treating empty lines as a terminator if set to the null string. (An empty line cannot contain any spaces or tabs.) You may set it to a multi-character string to match a multi-character terminator, or to undef to read through the end of file. Setting it to "\n\n" means something slightly different than setting to "", if the file contains consecutive empty lines. Setting to "" will treat two or more consecutive empty lines as a single empty line. Setting to "\n\n" will blindly assume that the next input character belongs to the next paragraph, even if it's a newline. (Mnemonic: / delimits line boundaries when quoting poetry.)  
    undef $/;           # enable "slurp" mode
    $_ = <FH>;          # whole file now here
    s/\n[ \t]+/ /g;
Remember: the value of $/ is a string, not a regex. awk has to be better for something. :-)
 
Setting $/ to a reference to an integer, scalar containing an integer, or scalar that's convertible to an integer will attempt to read records instead of lines, with the maximum record size being the referenced integer. So this:
 
    $/ = \32768; # or \"32768", or \$var_containing_32768
    open(FILE, $myfile);
    $_ = <FILE>;
will read a record of no more than 32768 bytes from FILE. If you're not reading from a record-oriented file (or your OS doesn't have record-oriented files), then you'll likely get a full chunk of data with every read. If a record is larger than the record size you've set, you'll get the record back in pieces.
 
On VMS, record reads are done with the equivalent of sysread, so it's best not to mix record and non-record reads on the same file. (This is unlikely to be a problem, because any file you'd want to read in record mode is probably unusable in line mode.) Non-VMS systems do normal I/O, so it's safe to mix record and non-record reads of a file.


 
En hopant que ça helpe...
A+,


Message édité par gilou le 16-04-2008 à 15:10:25

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-04-2008 à 17:53:23    

Merci pour toutes ces explications
 
Il semble bien que se soit le $/ le responsable :)
un ord($/) me confirme que ce bien l'ascii 10 (LF) le séparateur par defaut
 
Je testerais demain un truc du genre

Code :
  1. my $oldSep = $/;
  2. $/ = chr(13);


 
Avant mon appel de qx
 
Merci
 
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed