dans matlab mon programme sait que mon fichier s'appelle fichier.csv
donc si iil y a toujours un fichier.csv avec un contenu différent elle le fera toujours.
dans matlab mon programme sait que mon fichier s'appelle fichier.csv
donc si iil y a toujours un fichier.csv avec un contenu différent elle le fera toujours.
C'est un peu bancale ton truc ... n'est-il pas possible de passer en paramètre ce fichier d'entrée à Matlab ?
Et concernant le fichier de sortie de Matlab ? il aura aussi toujours le même nom fichier.xls ?
Il est important d'être précis dans ta réponse : le nom du fichier d'entrée de Matlab sera "fichier.csv" (et non pas le nom du fichier .eur avec une extension .csv) ? Exemple de processus :
- fichier d'entrée : toto.eur
- le script perl produit un fichier : fichier.csv
- Matlab utilise fichier.csv et produit fichier.xls
- on renomme fichier.xls en toto.xls
Est-ce bien cela que tu souhaites ?
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
c'est ca!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 ]fichier d'entrée : toto.eur le script perl produit un fichier : fichier.csv Matlab utilise fichier.csv et produit fichier.xls on renomme fichier.xls en toto.xls .
exactement
pour Matlab, ca devrait être possible, seulement je ne sais pas le faire, le fichier est importé de la source donc il reconnait le nom du fichier. Il y a peut etre une manière pour le mettre en paramètre, je cherche ca
Voici la 3e version de mon script :
Question subsidiaire : c'est un devoir pour l'école ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243 #!/usr/bin/perl use strict; use warnings; use feature qw(:5.14); use File::Copy; # Le fichier résultat sera la sortie standard : utiliser > un_fichier.txt pour le stocker # sauf si l'option -e=<extension> est utilisée. Dans ce cas, un fichier avec l'extension # est créé, et une commande matlab est exécutée # Récupération des paramètres d'appel du script (on affecte au tableau @in, le tableau @ARGV) my @in = @ARGV; @in = map /[\*\?]/ ? glob($_) : $_, @in; my ($file_ext) = map /^-e=(.*)$/, @in; @in = grep !/^-[e]/, @in; if (my @unknown_options = grep /^-/, @in) { die "Unknown option(s): @unknown_options"; } warn "Files will be treated one by one, each output file will be of the form <input_file>.$file_ext" if $file_ext; # Pour tous les fichier en entrée sub decode81($$); sub decode88($;$); foreach my $in (@in) { warn "Treating $in...\n"; # Ouvrir le fichier d'entrée en lecture open my $IN, "<", $in or die "Can't open file $in for reading: $!"; # Ouvrir un fichier de sortie en écriture (si option -ext=<extension>) my $out = "$in.$file_ext" if $file_ext; open my $OUT, ">", $out or die "Can't open file $out for writing: $!" if $out; # Déclarer un tableau pour les lignes 88 lues avant la ligne 81 # et un scalaire pour le code décimal my (@kept_lines, $decoded); # Boucler sur toutes les lignes du fichier ouvert en entrée while (my $line = <$IN>) { # Supprimer les caractères de fin de ligne (mettre à jour la variable # $/ s'il ne s'agit pas de \n) chomp($line); # Récupération du timestamp et du code hexa de la ligne my ($timestamp, $code) = $line =~ /(.*?,).*,([\da-f]+)$/i; # Passer à la ligne suivante si le code n'est ni 81 ni 88 next if !$code || $code !~ /^8[18]/; if ($code =~ /^81/) { # Si l'on a déjà décodé un code, le signaler, sinon simplement # indiquer que l'on décode warn "Line to decode found at $. in $in\n" if !$decoded; warn "New line to decode at $. in $in\n" if $decoded; # Sauvegarde de l'éventuel code décimal actuellement déjà décodé my $old_decoded = $decoded if $decoded; $decoded = decode81($code, $old_decoded); # Si l'on a stocké des lignes 88 précédent cette ligne 81, les traiter en ajoutant le code décimal if (@kept_lines) { map { say { $OUT // *STDOUT } sprintf $_, $decoded } splice @kept_lines; } } # Si la ligne n'est pas une 81 (c'est donc forcément une 88) else { # Décoder la ligne 88 if ($code = decode88($code, $decoded)) { # Si le code décimal a été décodé # traiter la ligne en ajoutant le code décimal au timestamp et au code hexa if ($decoded) { say { $OUT // *STDOUT } "$timestamp$code"; } # Si la ligne n'est pas une 81 et que le code n'est pas décodé, enregistrer la ligne (timestamp et code hexa) pour un traitement # ultérieur (lors du traitement de la ligne 81 ; le code de la ligne n'étant pas encore connu, il est remplacé par %s qui servira de template pour sprintf) else { push @kept_lines, "$timestamp$code"; } } } } undef $OUT; if ($out) { # Si l'option -e a été fournie, il faut appeler matlab avec le fichier $out renommé en "fichier.csv" # Ici, on fait une copie pour garder le fichier $out intermédiaire (on peut utiliser rename à la place) copy $out, "fichier.csv" or die "Can't create fichier.csv"; # On appelle Matlab system("matlab -wait -r programme"); # On renomme le résultat "fichier.xls" produit par Matlab en "$in.xls". # On ajoute simplement l'extension .xls au fichier d'entrée, c'est une mesure simplificatrice. # On aurait aussi pu modifier l'extension du fichier d'entrée (rename "fichier.xls", $in =~ s/\.([^\.]+)$/.xls/r) rename "fichier.xls", "$in.xls"; } } sub bin2hex($;$$) { my ($bitcode, $group, $msb_first) = @_; # Si $group est défini, on regroupe les bits par paquets de $group et on traite les groupes comme des digits décimaux limités à 9 # Si $group non défini, pas de regroupement, on traite la chaine de bit en un morceau) # Par défaut, MSB first $msb_first //= 1; # La construction suit plusieurs étapes (pipeline de fonction à lire de droite à gauche) : # 1- substr($bitcode, $bitpos, 32) =~ /(.{$group})/g : récupère le code binaire ASCII de 32 à la position $bitpos # et en extrait un tableau de chaines de $group digit binaires # grâce à une recherche d'expression régulière globale # 2- map oct("0b$_") : pour chaque chaine binaire de 4 digits, convertir le code binaire ASCII en valeur numérique # 3- grep $_ < 10 : pour chaque valeur numérique, ne conserver que les valeurs inférieures à 10 # 4- dans le cas LSB first, inverser les bits # 5- join "" : concaténer sous forme "chaine" les digits décimaux ($decoded est alors une chaine # mais qui peut être utilisée dans un contexte numérique comme une valeur numérique) my @bits = $group ? grep $_ < 10, map oct("0b$_"), $bitcode =~ /(.{$group})/g : oct("0b$bitcode"); map reverse, @bits if !$msb_first; return join "", @bits; } sub decode81($$) { my ($code, $old_decoded) = @_; # Convertir le code hexa en binaire # La transformation s'opère en deux temps : # pack("H*", $code) code en "binaire" le code hexa récupéré sous forme ASCII # puis unpack("B*", ...) décode le "binaire" en code binaire sous forme ASCII # "binaire" signifiant ici de vrai binaire numérique (comme il est stocké dans un entier numérique). # Les formats majuscules imposent un sens de code hexa et binaire "MSB" first (bit de poids fort en premier) my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 185, 1) eq "1" ? 217 : 209; } else { $bitpos = substr($bitcode, 200, 1) eq "1" ? 232 : 224; } } elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); if ($bit194 eq "00" || $bit194 eq "11") { $bitpos = substr($bitcode, 209, 1) eq "1" ? 241 : 232; } else { $bitpos = substr($bitcode, 222, 1) eq "1" ? 254 : 246; } } # Construction du code décimal my $decoded = bin2hex(substr($bitcode, $bitpos, 32), 4) if $bitpos; # Trivial if ($old_decoded) { if ($decoded != $old_decoded) { warn "-> new decoded value is different from first occurence: old = $old_decoded, new = $decoded\n"; } else { warn "-> same value ($decoded == $old_decoded)\n"; } } return $decoded; } sub decode88($;$) { my ($code, $code81) = @_; my $decoded = $code; # Si le code de la ligne 81 n'est pas encore connu, il est remplacé par %s qui servira de template pour sprintf $code81 //= "%s"; my @decoded = ($code81); # Convertir le code hexa en binaire my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { # Test du bit 186 if (substr($bitcode, 185, 3) ne "011") { $decoded = undef; } } else { # test du bit 201 if (substr($bitcode, 200, 3) ne "011") { $decoded = undef; } } } elsif ($bit75 eq "00000001") { my $bit195 = substr($bitcode, 194, 2); if ($bit195 eq "00" || $bit195 eq "11") { # Test du bit 210 if (substr($bitcode, 209, 3) ne "011") { $decoded = undef; } } else { # test du bit 225 if (substr($bitcode, 224, 3) ne "011") { $decoded = undef; } } } if ($decoded) { # Decoder les bit 51 à 74 push @decoded, bin2hex(substr($bitcode, 50, 74-50), undef, 0); # Decoder les bits 108 à 122 push @decoded, bin2hex(substr($bitcode, 107, 122-107), undef, 0); # Test du bit 82 pour décodage dernière colonne my $bit82 = substr($bitcode, 81, 1); my $last_col = bin2hex(substr($bitcode, $bit82 eq "0" ? 122 : 146, $bit82 eq "0" ? 138-122 : 162-146), undef, 0); # Decodage du multiplicateur my $bit96 = substr($bitcode, 95, 2); my $multi = $bit96 eq "00" || $bit96 eq "10" ? 10 : $bit96 eq "01" ? 1 : undef; my $last_col_unit = $bit96 eq "00" ? "cm" : $bit96 eq "01" || $bit96 eq "10" ? "m" : ""; push @decoded, ($last_col * $multi).$last_col_unit if $multi; $decoded = join "\t", $code, @decoded; } return $decoded; }
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
du coup j'envoie quoi dans la commande
C'est pour un stage.
Code : Sélectionner tout - Visualiser dans une fenêtre à part perl nomduprogramme.pl nomdudossier > ?
je vois pas l'endroit où intervient le programme matlab ?
rectification j'ai vu où matlab intervient mais j'envoie quoi en commande perl ?
Pardon, j'ai oublié de te préciser la syntaxe :
Pour l'option -e=csv, tu peux remplacer csv par une autre extension. Cette option permet de paramétrer le fonctionnement avec Matlab et "un fichier à la fois".
Code : Sélectionner tout - Visualiser dans une fenêtre à part perl script.pl *.eur -e=csv
Si tu ne mets pas cette option, le script se comporte comme avant (et tu es obligé de rediriger la sortie dans un fichier avec > fichier).
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
j'ai lancé le script et j'ai eu comme réponse
Code : Sélectionner tout - Visualiser dans une fenêtre à part Files will be treated one by one, each output file will be of the form >input_files>.csv at c:\chemin de mon programme
et je peux mettre en sortir un >dossier ?
C'est juste une information... tu n'as rien à faire de plus. Vérifie le contenu de ton dossier.
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
matlab s'execute bien mais j'ai un souci interne à mon programme, j'essaye de régler et je reviens pour savoir si ca fonctionne
le fichier.csv doit etre créé ? placé dans le dossier des fichiers *.eur?
car je crois qu'il y a un souci par rapport à lui
Le fichier "fichier.csv" est créé par le script perl avant de lancer Matlab par l'instruction copy $out, "fichier.csv" or die "Can't create fichier.csv";
Je vais être en congé à partir de "dans une 1h max" jusqu'à lundi matin.
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
Bon congé
ca me créé un .eur.csv et pas de .xls
du coup ca s'arrete à un fichier
pour lej'ai tenté ca , pour ne pas avoir d'unité mais etre sur que ca soit en mettre , 1cm= 0.01m donc multiplier par 0.01 mais il est écrit: Global symbol "$multi" requires explicit packagename, pareil pour $last_col_unit
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 # Decodage du multiplicateur my $bit96 = substr($bitcode, 95, 2); my $multi = $bit96 eq "00" ? 0.01|| $bit96 eq "10" ? 10 : $bit96 eq "01" ? 1 : undef; my $last_col_unit = $bit96 eq "00" ? "" : $bit96 eq "01" || $bit96 eq "10" ? "" : ""; push @decoded, ($last_col * $multi).$last_col_unit if $multi;
pour le lancement général ce qui se passe est que: le programme se lance matlab s'ouvre, message d'erreur dans matlab, je vais donc voir dans le dossier ce qu'il a créé, et la il a créé un fichier .eur.csv et il y a deja plus de fichier.csv , je ne sais pas s'il se créé vraiment du coup
Pour le problème Matlab, tu as l'air d'avoir appelé le script avec le bon paramètre (-e=csv)... du coup, je ne vois rien de plus que débugger le script pour comprendre.
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
Désolée j'ai pas pu prévenir, j'avais un probleme de position de fichier, mais finalement ca fonctionne parfaitement
Bonjour, en fait j'ai un probleme avec le debut du programme.
il affiche 9819405 au debut dans la premiere colonne
et 819405 par la suite, or seul le deuxieme resultat est exact
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 2013/06/16 03:10:25,198,1819,B->R01,9B0280005262083FFF4000000000 2013/06/16 03:10:27,017,1489,R01->B,2002C00052941FFFFFE40000000000 2013/06/16 03:10:28,198,1802,B->R01,9F09400052AD083FFF40C1B430033669818199FFF0033669818197FFF0033669818195FFF000000000 2013/06/16 03:10:28,348,2165,B->R01,8806400052B0C83FFF4000F4FFFFFFFFFFA0294052459690E000000000 2013/06/16 03:10:30,513,1489,R01->B,1804800052E2DFFFFFE7500E178FFFE41FE000000000 2013/06/16 03:10:28,498,2535,B->R01,810B000052B4883FFF4000F4FFFFFFFFFFA0296052459690E0B04D40CA02FF80000F0800E89180810188203800000000 2013/06/16 03:10:31,033,1489,R01->B,0803800052E69FFFFFE000295A4000000000 2013/06/16 03:10:34,048,1962,B->R01,88064000533F483FFF4000F49000CC00270001A003458690E000000000 2013/06/16 03:10:41,098,1912,B->R01,8806400053EF883FFF4000F490001300270001A00345A690E000000000 2013/06/16 03:10:54,748,1752,B->R01,880640005544C83FFF4000F490001600395001A00345CE90E000000000 2013/06/16 03:30:51,748,1642,B->R03,88060000CA29C83FFF4000E49005DF00265001A00345683000000000 2013/06/16 03:30:53,390,1489,R03->B,18054000CA5BC40177C9F0145177C0002355940FF000000000 2013/06/16 03:30:55,348,1549,B->R03,88060000CA83C83FFF4000E49005DF00F85001E003C5483000000000 2013/06/16 03:30:56,897,1489,R03->B,18054000CAB5C40177C9F0145177C0002355940FF000000000 2013/06/16 03:31:00,448,1935,B->R03,88060000CB03483FFF4000E49005DF021B5002200445083000000000 2013/06/16 03:31:02,383,1489,R03->B,18054000CB35440177C9F0145177C0002355940FF000000000 2013/06/16 03:31:05,548,1832,B->R03,88060000CB82C83FFF4000E49005DF03355002400484E83000000000 2013/06/16 03:31:07,380,1489,R03->B,18054000CBB4C40177C9F0145177C0002355940FF000000000 2013/06/16 03:31:07,648,1755,B->R03,88060000CBB7483FFF4000E49005E000275001A00344C83000000000 2013/06/16 03:31:09,403,1489,R03->B,18054000CBE944017809F01451780000235C920FF000000000 2013/06/16 03:31:10,648,1729,B->R03,88060000CC02483FFF4000E49005E000C25001C00384883000000000
À partir de ce seul fichier exemple que tu donnes, je n'obtiens de mon coté que la valeur 9819405 pour la première colonne. A savoir :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 2013/06/16 03:30:51,88060000CA29C83FFF4000E49005DF00265001A00345683000000000 9819405 2162685 6012 153m 2013/06/16 03:30:55,88060000CA83C83FFF4000E49005DF00F85001E003C5483000000000 9819405 2162685 6012 993m 2013/06/16 03:31:00,88060000CB03483FFF4000E49005DF021B5002200445083000000000 9819405 2162685 6012 2157m 2013/06/16 03:31:05,88060000CB82C83FFF4000E49005DF03355002400484E83000000000 9819405 2162685 6012 3285m 2013/06/16 03:31:07,88060000CBB7483FFF4000E49005E000275001A00344C83000000000 9819405 2162685 6016 157m 2013/06/16 03:31:10,88060000CC02483FFF4000E49005E000C25001C00384883000000000 9819405 2162685 6016 777m
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
Le fichier étant trop gros je ne peux pas le mettre en entier malheureusement.
des lignes de la fin pour être sur
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 2013/06/16 00:32:41,440,1491,R07->B,18054001C51884036C09F014536C0000082EB60FF000000000 2013/06/16 00:32:44,776,2181,B->R07,88060001C566083FFF4000E4900DB003A50002800503E03000000000 2013/06/16 00:32:46,957,1491,R07->B,18054001C59804036C09F014536C0000082EB60FF000000000 2013/06/16 00:32:49,876,2077,B->R07,88060001C5E5883FFF4000E4900DB004850002A00544003000000000 2013/06/16 00:32:51,953,1491,R07->B,18054001C61784036C09F014536C0000082EB60FF000000000 2013/06/16 00:32:51,076,1871,B->R07,88060001C603883FFF4000E4900E7C001C0001A00344003000000000 2013/06/16 00:32:52,947,1491,R07->B,18054001C63584039F09F014539F00000003800FF000000000 2013/06/16 00:32:54,976,1964,B->R07,88060001C665083FFF4000E4900E7D00220001A00344003000000000 2013/06/16 00:32:56,940,1491,R07->B,18054001C69704039F49F014539F40000004D20FF000000000 2013/06/16 00:32:56,626,1817,B->R07,88060001C68E483FFF4000E4900E7E001F5001A00344083000000000 2013/06/16 00:32:58,443,1491,R07->B,18054001C6C044039F89F014539F800020056A0FF000000000 2013/06/16 00:33:00,076,1891,B->R07,88060001C6E4883FFF4000E4900E7E00B65001C00384083000000000 2013/06/16 00:33:01,967,1491,R07->B,18054001C71684039F89F014539F800020056A0FF000000000 2013/06/16 00:33:05,176,1761,B->R07,88060001C764083FFF4000E4900E7E01935002000403E83000000000 2013/06/16 00:33:06,937,1491,R07->B,18054001C79604039F89F014539F800020056A0FF000000000 2013/06/16 00:33:07,126,1811,B->R07,88060001C794C83FFF4000E4900E7F00200001A00343E03000000000 2013/06/16 00:33:08,937,1491,R07->B,18054001C7C6C4039FC9F014539FC0000008FA0FF000000000 2013/06/16 00:33:10,276,1657,B->R07,88060001C7E3883FFF4000E4900E7F00A90001C00383E03000000000 2013/06/16 00:33:11,933,1491,R07->B,18054001C81584039FC9F014539FC0000008FA0FF000000000 2013/06/16 00:33:15,376,2054,B->R07,88060001C863083FFF4000E4900E7F01860002000403E03000000000 2013/06/16 00:33:17,430,1491,R07->B,18054001C89504039FC9F014539FC0000008FA0FF000000000 2013/06/16 00:33:15,526,2414,B->R07,88060001C866C83FFF4000E4900E80001E5001A00343E83000000000 2013/06/16 00:33:17,940,1491,R07->B,18054001C898C403A009F01453A00000200BDA0FF000000000 2013/06/16 00:33:19,576,1861,B->R07,88064001C8CC083FFF4000F4900E8100225001A00343EE908000000000 2013/06/16 00:33:21,437,1491,R07->B,18064001C8FE0403A045501C440000E0066D2723200FFFFFF000000000 2013/06/16 00:33:22,576,1854,B->R07,9C028001C917083FFF4000000000 2013/06/16 00:33:24,430,1491,R07->B,27028001C9490403A04000000000
mais j'obtiens au debut 9819405 et ensuite 819405
Même avec cet extrait plus gros, j'obtiens toujours qu'un seul résultat. Cependant, je comprend qu'il doit y avoir plusieurs lignes 81 à décoder dans ton fichier.
A l'époque, quand je t'avais demandé comment faire, je crois me souvenir que tu n'avais pas été très précis. Ce qui est fait actuellement est que :
- dès qu'on décode une ligne 81, les lignes 88 suivantes sont affichée avec ce code
- si l'on détecte une nouvelle ligne 81, le nouveau code est utilisé pour afficher les lignes 88 qui suivent (et un message d'information est affiché à l'écran).
D'après ce que tu sembles attendre, il ne faudrait pas utiliser le premier code décodé, mais alors lequel ? le 2e, le 3e, le dernier ?
Tu dois être plus précis dans tes spécifications. Car sans spécification, l'implémentation est laissée au bon gré du programmeur
Plus j'apprends, et plus je mesure mon ignorance (philou67430)
Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
Si c'est utile, say
Une seule ligne 81 me suffit, je la décode et elle donne un résultat et ce résultat est affecté à coté de toutes les lignes 88.
Voici la dernire version de mon programme, peut etre que quelquechose ne va pas dedans.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294 #!/usr/bin/perl use strict; use warnings; use feature qw(:5.14); use File::Copy; # Le fichier résultat sera la sortie standard : utiliser > un_fichier.txt pour le stocker # sauf si l'option -e=<extension> est utilisée. Dans ce cas, un fichier avec l'extension # est créé, et une commande matlab est exécutée # Récupération des paramètres d'appel du script (on affecte au tableau @in, le tableau @ARGV) my @in = @ARGV; @in = map /[\*\?]/ ? glob($_) : $_, @in; my ($file_ext) = map /^-e=(.*)$/, @in; @in = grep !/^-[e]/, @in; if (my @unknown_options = grep /^-/, @in) { die "Unknown option(s): @unknown_options"; } warn "Files will be treated one by one, each output file will be of the form <input_file>.$file_ext" if $file_ext; # Pour tous les fichier en entrée sub decode81($$); sub decode88($;$); foreach my $in (@in) { warn "Treating $in...\n"; # Ouvrir le fichier d'entrée en lecture open my $IN, "<", $in or die "Can't open file $in for reading: $!"; # Ouvrir un fichier de sortie en écriture (si option -ext=<extension>) my $out = "$in.$file_ext" if $file_ext; open my $OUT, ">", $out or die "Can't open file $out for writing: $!" if $out; # Déclarer un tableau pour les lignes 88 lues avant la ligne 81 # et un scalaire pour le code décimal my (@kept_lines, $decoded); # Boucler sur toutes les lignes du fichier ouvert en entrée while (my $line = <$IN>) { # Supprimer les caractères de fin de ligne (mettre à jour la variable # $/ s'il ne s'agit pas de \n) chomp($line); # Récupération du timestamp et du code hexa de la ligne my ($timestamp, $code) = $line =~ /(.*?),.*,([\da-f]+)$/i; # Passer à la ligne suivante si le code n'est ni 81 ni 88 next if !$code || $code !~ /^8[18]/; if ($code =~ /^81/) { # Si l'on a déjà décodé un code, le signaler, sinon simplement # indiquer que l'on décode warn "Line to decode found at $. in $in\n" if !$decoded; warn "New line to decode at $. in $in\n" if $decoded; # Sauvegarde de l'éventuel code décimal actuellement déjà décodé my $old_decoded = $decoded if $decoded; $decoded = decode81($code, $old_decoded); # Si l'on a stocké des lignes 88 précédent cette ligne 81, les traiter en ajoutant le code décimal if (@kept_lines) { map { say { $OUT // *STDOUT } sprintf $_, $decoded } splice @kept_lines; } } # Si la ligne n'est pas une 81 (c'est donc forcément une 88) else { # Décoder la ligne 88 if ($code = decode88($code, $decoded)) { # Si le code décimal a été décodé # traiter la ligne en ajoutant le code décimal au timestamp et au code hexa if ($decoded) { say { $OUT // *STDOUT } "$timestamp;$code"; } # Si la ligne n'est pas une 81 et que le code n'est pas décodé, enregistrer la ligne (timestamp et code hexa) pour un traitement # ultérieur (lors du traitement de la ligne 81 ; le code de la ligne n'étant pas encore connu, il est remplacé par %s qui servira de template pour sprintf) else { push @kept_lines, "$timestamp;$code"; } } } } undef $OUT; if ($out) { # Si l'option -e a été fournie, il faut appeler matlab avec le fichier $out renommé en "fichier.csv" # Ici, on fait une copie pour garder le fichier $out intermédiaire (on peut utiliser rename à la place) rename $out, "fichier.csv" or die "Can't create fichier.csv"; # On appelle Matlab system("matlab -wait -r programme"); # On renomme le résultat "fichier.xls" produit par Matlab en "$in.xls". # On ajoute simplement l'extension .xls au fichier d'entrée, c'est une mesure simplificatrice. # On aurait aussi pu modifier l'extension du fichier d'entrée (rename "fichier.xls", $in =~ s/\.([^\.]+)$/.xls/r) my $out = $in; $out =~ s/.eur/.xls/; rename "fichier.xls", "$out"; } } sub bin2hex($;$$) { my ($bitcode, $group, $msb_first) = @_; # Si $group est défini, on regroupe les bits par paquets de $group et on traite les groupes comme des digits décimaux limités à 9 # Si $group non défini, pas de regroupement, on traite la chaine de bit en un morceau) # Par défaut, MSB first $msb_first //= 1; # La construction suit plusieurs étapes (pipeline de fonction à lire de droite à gauche) : # 1- substr($bitcode, $bitpos, 32) =~ /(.{$group})/g : récupère le code binaire ASCII de 32 à la position $bitpos # et en extrait un tableau de chaines de $group digit binaires # grâce à une recherche d'expression régulière globale # 2- map oct("0b$_") : pour chaque chaine binaire de 4 digits, convertir le code binaire ASCII en valeur numérique # 3- grep $_ < 10 : pour chaque valeur numérique, ne conserver que les valeurs inférieures à 10 # 4- dans le cas LSB first, inverser les bits # 5- join "" : concaténer sous forme "chaine" les digits décimaux ($decoded est alors une chaine # mais qui peut être utilisée dans un contexte numérique comme une valeur numérique) my @bits = $group ? grep $_ < 10, map oct("0b$_"), $bitcode =~ /(.{$group})/g : oct("0b$bitcode"); map reverse, @bits if !$msb_first; return join "", @bits; } sub decode81($$) { my ($code, $old_decoded) = @_; # Convertir le code hexa en binaire # La transformation s'opère en deux temps : # pack("H*", $code) code en "binaire" le code hexa récupéré sous forme ASCII # puis unpack("B*", ...) décode le "binaire" en code binaire sous forme ASCII # "binaire" signifiant ici de vrai binaire numérique (comme il est stocké dans un entier numérique). # Les formats majuscules imposent un sens de code hexa et binaire "MSB" first (bit de poids fort en premier) my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; #si paquet 0 if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); #Si Q_LENGTH égal 0 ou 3 if ($bit171 eq "00" || $bit171 eq "11") { #NID_OPERATIONAL $bitpos = substr($bitcode, 185, 1) eq "1" ? 217 : 209; } else { #NID_OPERATIONAL $bitpos = substr($bitcode, 200, 1) eq "1" ? 232 : 224; } } #Si paquet 1 elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); #Si Q_LENGTH égal 0 ou 3 if ($bit194 eq "00" || $bit194 eq "11") { #NID_OPERATIONAL $bitpos = substr($bitcode, 209, 1) eq "1" ? 241 : 232; } else { #NID_OPERATIONAL $bitpos = substr($bitcode, 222, 1) eq "1" ? 254 : 246; } } # Construction du code décimal my $decoded = bin2hex(substr($bitcode, $bitpos, 32), 4) if $bitpos; # Trivial if ($old_decoded) { if ($decoded != $old_decoded) { warn "-> new decoded value is different from first occurence: old = $old_decoded, new = $decoded\n"; } else { warn "-> same value ($decoded == $old_decoded)\n"; } } return $decoded; } sub decode88($;$) { my ($code, $code81) = @_; my $decoded = $code; # Si le code de la ligne 81 n'est pas encore connu, il est remplacé par %s qui servira de template pour sprintf $code81 //= "%s"; my @decoded = ($code81); # Convertir le code hexa en binaire my $bitcode = unpack("B*", pack("H*", $code)); my $bit75 = substr($bitcode, 74, 8); # Déclaration d'une variable qui contiendra la position des 32bits à décoder my $bitpos; if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { # Test du bit 186, M_LEVEL, si M_LEVEL différent de 3 (011) ce n'est pas un ERTMS niveau 2, donc on peut supprimer la ligne if (substr($bitcode, 185, 3) ne "011") { $decoded = undef; } } else { # test du bit 201, M_LEVEL, si M_LEVEL différent de 3 (011) ce n'est pas un ERTMS niveau 2, donc on peut supprimer la ligne if (substr($bitcode, 200, 3) ne "011") { $decoded = undef; } } } elsif ($bit75 eq "00000001") { my $bit195 = substr($bitcode, 194, 2); if ($bit195 eq "00" || $bit195 eq "11") { # Test du bit 210, M_LEVEL, si M_LEVEL différent de 3 (011) ce n'est pas un ERTMS niveau 2, donc on peut supprimer la ligne if (substr($bitcode, 209, 3) ne "011") { $decoded = undef; } } else { # test du bit 225, M_LEVEL, si M_LEVEL différent de 3 (011) ce n'est pas un ERTMS niveau 2, donc on peut supprimer la ligne if (substr($bitcode, 224, 3) ne "011") { $decoded = undef; } } } if ($decoded) { if ($bit75 eq "00000000") { my $bit171 = substr($bitcode, 170, 2); if ($bit171 eq "00" || $bit171 eq "11") { $bitpos = substr($bitcode, 172, 1) eq "1" ? 179 : 173; #décodage de la vitesse, multiplié par 5 push @decoded, 5*bin2hex(substr($bitcode, 172, 7), undef, 0); } else { $bitpos = substr($bitcode, 188, 1) eq "1" ? 194 : 188; #décodage de la vitesse, multiplié par 5 push @decoded, 5*bin2hex(substr($bitcode, 187, 7), undef, 0); } } elsif ($bit75 eq "00000001") { my $bit194 = substr($bitcode, 193, 2); if ($bit194 eq "00" || $bit194 eq "11") { $bitpos = substr($bitcode, 197, 1) eq "1" ? 203 : 197; #décodage de la vitesse, multiplié par 5 push @decoded, 5*bin2hex(substr($bitcode, 196, 7), undef, 0); } else { $bitpos = substr($bitcode, 211, 1) eq "1" ? 218 : 212; #décodage de la vitesse, multiplié par 5 push @decoded, 5*bin2hex(substr($bitcode, 211, 7), undef, 0); } } # Decoder les bit 51 à 74, NID_ENGINE push @decoded, bin2hex(substr($bitcode, 50, 74-50), undef, 0); # Decoder les bits 108 à 122, LRBG push @decoded, bin2hex(substr($bitcode, 107, 122-108), undef, 0); # Test du bit 82 pour décodage dernière colonne my $bit82 = substr($bitcode, 81, 1); #D_LRBG my $last_col = bin2hex(substr($bitcode, $bit82 eq "0" ? 121 : 145, $bit82 eq "0" ? 137-122 : 161-146), undef, 0); # Decodage du multiplicateur, pour le D_LRBG analyse du Q_LENGTH pour savoir si c'est en cm ou en m. my $bit96 = substr($bitcode, 95, 2); my $multi = $bit96 eq "00" || $bit96 eq "10" ? 10 : $bit96 eq "01" ? 1 : undef; my $last_col_unit = $bit96 eq "00" ? "cm" : $bit96 eq "01" || $bit96 eq "10" ? "m" : ""; push @decoded, ($last_col * $multi).$last_col_unit if $multi; #$decoded = join ";", $code, @decoded; #permet de supprimer le message 88, et de garder le reste, les colonnes sont donc respectivement: # date-heure, NID_OPERATIONAL, vitesse, NID_ENGINE,LRBG,D_LRBG. $decoded = join ";", @decoded; } return $decoded; }
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager