unpack et nombres réel issus de VMS.

Le
Thierry Thomas
Bonsoir,

Je dois récupérer un lot de données techniques qui avaient été créées
par des programmes Pascal sur un Vax (VMS), avec des formats INTEGER ou
REAL.

J'avais pensé à faire un script Perl pour les lire, à cause d'unpack, et
effectivement je récupère très bien les entiers, en mettant 'V' dans le
template. Par contre, je n'ai rien trouvé pour les réels, et il semble
que ça ne soit pas prévu dans l'unpack standard.

Y aurait-il un module complémentaire qui permette de lire ces réels ?

Merci.
--
Th. Thomas.
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Yves POINTIN
Le #142290
Thierry Thomas wrote:
Bonsoir,

Je dois récupérer un lot de données techniques qui avaient été créées
par des programmes Pascal sur un Vax (VMS), avec des formats INTEGER ou
REAL.

J'avais pensé à faire un script Perl pour les lire, à cause d'unpack, et
effectivement je récupère très bien les entiers, en mettant 'V' dans le
template. Par contre, je n'ai rien trouvé pour les réels, et il semble
que ça ne soit pas prévu dans l'unpack standard.

Y aurait-il un module complémentaire qui permette de lire ces réels ?

Merci.


Bonjour,

Voici une partie du code que j'ai utilisé sous Linux pour récupérer des
fichiers binaires écrits en FORTRAN (avec octets de contrôle) sous VAX

my @tbuf=`od -a $fich ` ;
my @pbuf=map(/[!^d{7}s+].+/g,@tbuf) ;
my $ligne="";
for my $ii (0..$#pbuf) {
$ligne=$ligne." ".$pbuf[$ii];
}
@tbuf=split(/s+/m,$ligne);
# print " t => @tbuf[0..40] n";
my @fbuf=`od -x $fich ` ;
$ligne="";
for my $ii (0..$#fbuf) {
$fbuf[$ii]=~ s/^d{7}s+// ;
$fbuf[$ii]=~ s/^*// ;
$ligne=$ligne." ".$fbuf[$ii];
}
# séparation et inversion des octets
$ligne=~ s/(w{2})(w{2})/$2 $1/g ;
@pbuf=split(/s+/m,$ligne);
# print " p => @pbuf[0..$#pbuf] n";
@fbuf=() ;
for (my $ii=1;$ii<= $#pbuf-3 ; $ii+=4) {
$fbuf[$ii/4]=unpack("f",pack("H8", substr("0" x 8
.$pbuf[$ii+2].$pbuf[$ii+3
].$pbuf[$ii].$pbuf[$ii+1], -8)))/4;
}

# print " f => @fbuf[0..$#pbuf/4] n";

Il fallait ensuite se resynchroniser sur les octets de contrôle au début
des enregistrements réels (code 66 , 3 , nombre de valeurs, en entier,
je crois)

Si ça peut servir.

Cordialement,

--
Dr. POINTIN Yves B.
perl -e "$_='';1 while
s/(.{3})(.{3})?/$_{$2}=$1,$2/e; ; print while $_=$_{$_};"

Paul Gaborit
Le #142288
À (at) Sat, 17 Mar 2007 21:13:23 +0000 (UTC),
Thierry Thomas
Je dois récupérer un lot de données techniques qui avaient été créées
par des programmes Pascal sur un Vax (VMS), avec des formats INTEGER ou
REAL.

J'avais pensé à faire un script Perl pour les lire, à cause d'unpac k, et
effectivement je récupère très bien les entiers, en mettant 'V' dan s le
template. Par contre, je n'ai rien trouvé pour les réels, et il semble
que ça ne soit pas prévu dans l'unpack standard.

Y aurait-il un module complémentaire qui permette de lire ces réels  ?


En module tout prêt, je ne sais pas. Mais avec les fonctions de base
de Perl, c'est faisable. Par contre, il vous faut en savoir un peu
plus sur sur le format de stockage des doubles (nombre d'octets
utilisés, little ou big endian, taille en bits de la mantisse et de
l'exposant,etc.) tant sur le VMS d'origine que sur la plateforme où
tourne votre script. Si en plus, vous avez quelques petits fichiers de
données dont le contenu est connu, c'est encore mieux pour faire les
tests ou même pour redécvourir tout cela. Après, ce n'est plus que de
la cuisine interne pour réordonner les octets voire les bits d'un
format natif à l'autre...

--
Paul Gaborit - Perl en français -
Paul Gaborit
Le #142191
À (at) Mon, 19 Mar 2007 10:31:05 +0100,
Yves POINTIN [...]
Voici une partie du code que j'ai utilisé sous Linux pour récupérer
des fichiers binaires écrits en FORTRAN (avec octets de contrôle) sous
VAX


Joli (!?!)... Tous les appels à 'od' aurait pu être gérer directement
en Perl. De plus, les enregistrements des fichiers binaires FORTRAN
sont un peu particulier (il y a effectivement un marqueur au début et
un à la fin). Ceci étant, il reste la partie sur l'ordonancement des
octets des valeurs flottantes qui est intéressantes (puisque
manifestement il n'y a que ça à faire). Mais là, l'ordre dépend de la
plateforme d'arrivée... qu'on ne connait pas encore.

--
Paul Gaborit - Perl en français -
Thierry Thomas
Le #142186
Lundi 19 mars 2007 à 10:25 GMT, Paul Gaborit a écrit :

Joli (!?!)... Tous les appels à 'od' aurait pu être gérer directement
en Perl. De plus, les enregistrements des fichiers binaires FORTRAN
sont un peu particulier (il y a effectivement un marqueur au début et
un à la fin). Ceci étant, il reste la partie sur l'ordonancement des
octets des valeurs flottantes qui est intéressantes (puisque
manifestement il n'y a que ça à faire). Mais là, l'ordre dépend de la
plateforme d'arrivée... qu'on ne connait pas encore.


Je ne connais pas encore la plate-forme finale avec certitude, mais ça
sera sans doute un i386 sous Linux.

Quoiqu'il en soit, je peux faire cette moulinette intermédiaire sur
n'importe quelle machine à ma disposition, le but serait de convertir
mes fichiers en CSV / ASCII avec des print.
--
Th. Thomas.

Thierry Thomas
Le #142088
Lundi 19 mars 2007 à 10:11 GMT, Paul Gaborit a écrit :

En module tout prêt, je ne sais pas. Mais avec les fonctions de base
de Perl, c'est faisable. Par contre, il vous faut en savoir un peu
plus sur sur le format de stockage des doubles (nombre d'octets
utilisés, little ou big endian, taille en bits de la mantisse et de
l'exposant,etc.) tant sur le VMS d'origine que sur la plateforme où
tourne votre script. Si en plus, vous avez quelques petits fichiers de
données dont le contenu est connu, c'est encore mieux pour faire les
tests ou même pour redécvourir tout cela. Après, ce n'est plus que de
la cuisine interne pour réordonner les octets voire les bits d'un
format natif à l'autre...


Comme unpack traitait les entiers, j'avais imaginé qu'il y aurait
quelque chose pour les réels... Mais s'il n'y a pas, je vais devoir
vaincre ma flemme et m'y coller ! Merci pour vos réponses.
--
Th. Thomas.

Paul Gaborit
Le #142087
À (at) Mon, 19 Mar 2007 18:09:15 +0000 (UTC),
Thierry Thomas
Comme unpack traitait les entiers, j'avais imaginé qu'il y aurait
quelque chose pour les réels... Mais s'il n'y a pas, je vais devoir
vaincre ma flemme et m'y coller ! Merci pour vos réponses.


Pour la lecture du fichier, les fonctions à utiliser sont sysopen() et
sysread() en lisant si possible, par petits morceaux de taille connue.

Pour faire une première décomposition de ce qui est lu, unpack() en
lisant directement les entiers (via le bon type selon la plateforme
d'origine) et en lisant un simple groupe d'octets pour chaque flottant
(il faut quand même connaître sa taille).

Pour réordonner les octets ou même les bits au sein d'un flottant (vu
comme un groupes d'octets ou de bits), on peut utiliser vec().

Avec de la chance, un simple réordonnancement des octets suffit et on
peut ensuite utiliser les types flottants natifs de unpack ('f' ou
'd') pour relire les flottants.

Mais dans le cas où le nombre de bits de la mantisse ou de l'exposant
serait différent entre les plateformes, il faudra faire des choix
limitatifs (et tout faire via vec() pour extraire mantisse et exposant
séparément).

Mais, c'est faisable et très agréable à coder avec Perl.

--
Paul Gaborit - Perl en français -
Paul Gaborit
Le #142086
À (at) Tue, 20 Mar 2007 01:29:07 +0100,
Paul Gaborit
Pour la lecture du fichier, les fonctions à utiliser sont sysopen() et
~~~~~~~~~~~

sysread() en lisant si possible, par petits morceaux de taille connue.


Un simple open() suivit de binmode() suffit amplement pour ouvrir le
fichier en mode binaire sur toute les plateformes. Et toc ! ;-)

--
Paul Gaborit - Perl en français -
Nicolas George
Le #142085
Paul Gaborit wrote in message
Pour la lecture du fichier, les fonctions à utiliser sont sysopen() et
sysread() en lisant si possible, par petits morceaux de taille connue.


Quelle drôle d'idée. sysopen est utile quand on veut contrôler finement les
options d'ouverture, sysread pour travailler avec des fichiers spéciaux sans
tampon. Mais ici, ça me semble absolument inutile et plutôt une mauvaise
idée.

Paul Gaborit
Le #142084
À (at) 20 Mar 2007 11:19:45 GMT,
Nicolas George
Paul Gaborit wrote in message
Pour la lecture du fichier, les fonctions à utiliser sont sysopen() et
sysread() en lisant si possible, par petits morceaux de taille connue.


Quelle drôle d'idée. sysopen est utile quand on veut contrôler finement les
options d'ouverture, sysread pour travailler avec des fichiers spéciaux sans
tampon. Mais ici, ça me semble absolument inutile et plutôt une mauvaise
idée.


Oui, oui. Je voulais insister sur sysread() qui, dans ce cas, est
absolument nécessaire et emporté par mon élan, j'ai tapé sysopen() au
lieu de open() (suivi de binmode())...

--
Paul Gaborit - Perl en français -

Nicolas George
Le #142083
Paul Gaborit wrote in message
Oui, oui. Je voulais insister sur sysread() qui, dans ce cas, est
absolument nécessaire


Pourquoi donc ?

Publicité
Poster une réponse
Anonyme