Réorganisations de données dans un fichier en Perl
débutPerl
-
[Dal] Messages postés 6373 Statut Contributeur -
[Dal] Messages postés 6373 Statut Contributeur -
Bonjour,
Tout d'abord merci pour cet espace très utile qui m'a fourni de nombreuses solutions en perl. Cependant je suis encore débutant et face au problème suivant:
Je cherche à transformer un fichier.txt ayant ce format :
---------------------------
-------------------------
au format suivant :
-------------------------
-------------------------
Trois actions me pose donc problème :
- récupérer le contenu des lignes comprise entre deux ligne bien particulière tel exemple1.flac et exemple2.flac
- convertir le temps du format hh:mm:ss,fff au format ssss,fff
- réorganiser ces informations dans l'ordre voulu, soit: début fin étiquette
Ce morceau de code me permet d'afficher le contenu des lignes avec une étiquette mais pas de séparer les différente portions. (chaque ligne est étiquetée avec exemple1 indifféremment)
Pour la conversion, je suis arrivé à ce code :
Mais il ne convient pas tout à fait...
Je serais extrêmement reconnaissant pour toute aide !!! Merci
Tout d'abord merci pour cet espace très utile qui m'a fourni de nombreuses solutions en perl. Cependant je suis encore débutant et face au problème suivant:
Je cherche à transformer un fichier.txt ayant ce format :
---------------------------
exemple1.flac # (durée exemple1 = 66 centièmes de secondes)
00:21:29,642
00:23:15,628
exemple2.flac #(durée exemple2 = 1 seconde et 016 centièmes)
00:29:26,812
00:35:43,056
00:44:37,231
..etc
-------------------------
au format suivant :
-------------------------
1289,642 1290,302 exemple1
1395,628 1396,288 exemple1
1766,811 1767,828 exemple2
2143,055 2144,072 exemple2
2391,496 2392,512 exemple2
-------------------------
Trois actions me pose donc problème :
- récupérer le contenu des lignes comprise entre deux ligne bien particulière tel exemple1.flac et exemple2.flac
- convertir le temps du format hh:mm:ss,fff au format ssss,fff
- réorganiser ces informations dans l'ordre voulu, soit: début fin étiquette
while (<$in>) { # LIT et regarde si la fin du fichier est atteinte
($ligne=$_);
@listeCase = split(/\n/,$ligne);
foreach $case (@listeCase) {
if (my @res = grep { $_ =~ /00\:(\d\d)\:(\d\d),(\d\d\d)/ } @listeCase) {
print "$case\t exemple1\n";
}
Ce morceau de code me permet d'afficher le contenu des lignes avec une étiquette mais pas de séparer les différente portions. (chaque ligne est étiquetée avec exemple1 indifféremment)
Pour la conversion, je suis arrivé à ce code :
if ($temps=~/00\:(\d\d)\:(\d\d),(\d\d\d)/) {
my $minute = $1;
my $seconde = $2;
my $centieme = $3;
my $min = (($minute * 60) + $seconde);
print "minutes : $min,$centieme \n";
}
Mais il ne convient pas tout à fait...
Je serais extrêmement reconnaissant pour toute aide !!! Merci
A voir également:
- Réorganisations de données dans un fichier en Perl
- Fichier bin - Guide
- Comment réduire la taille d'un fichier - Guide
- Comment ouvrir un fichier epub ? - Guide
- Fichier rar - Guide
- Fichier .dat - Guide
1 réponse
Dia duit débutPerl,
Si je ne me trompe pas, dans le format de résultat, la ligne "1289,642 1290,302 exemple1" est formée en :
- convertissant "00:21:29,642" en secondes et millièmes, et en affichant cela, soit "1289,642"
- en ajoutant à cette valeur 66 centièmes de secondes, et en affichant cela, soit "1290,302", cette valeur de 66 centièmes semblant provenir de la première ligne du bloc "exemple1.flac # (durée exemple1 = 66 centièmes de secondes)"
- en affichant "exemple1.flac", cette chaîne semblant provenir de la même première ligne "exemple1.flac # (durée exemple1 = 66 centièmes de secondes)"
Tu n'as pas du tout expliqué ce qui est en gras.
Comment sais-tu quelle valeur ajouter pour obtenir le 2nd chiffre ?
Dois-tu le dériver du texte libre mis en commentaire ?
Dans ton exemple, le texte affiché en commentaire sur la durée a un format variable selon que la durée dure plus ou moins d'une seconde :
quel est le format s'il y a au moins deux secondes ?
quel est le format s'il y a plus de 60 secondes ?
quel est le format s'il y a plus de 60 minutes ?
(etc. jours, mois,... on peut aller loin comme çà)
les temps d'origine sont en heures, minutes, secondes et millièmes de secondes. Dans le temps a ajouter, peut-il y avoir des millièmes aussi ? Si oui, les centièmes sont-ils alors aussi mentionnés ou la mention des millièmes remplace-t-elle celle des centièmes ?
Par curiosité, d'où vient ce fichier et c'est pour quoi faire ?
Dal
Si je ne me trompe pas, dans le format de résultat, la ligne "1289,642 1290,302 exemple1" est formée en :
- convertissant "00:21:29,642" en secondes et millièmes, et en affichant cela, soit "1289,642"
- en ajoutant à cette valeur 66 centièmes de secondes, et en affichant cela, soit "1290,302", cette valeur de 66 centièmes semblant provenir de la première ligne du bloc "exemple1.flac # (durée exemple1 = 66 centièmes de secondes)"
- en affichant "exemple1.flac", cette chaîne semblant provenir de la même première ligne "exemple1.flac # (durée exemple1 = 66 centièmes de secondes)"
Tu n'as pas du tout expliqué ce qui est en gras.
Comment sais-tu quelle valeur ajouter pour obtenir le 2nd chiffre ?
Dois-tu le dériver du texte libre mis en commentaire ?
Dans ton exemple, le texte affiché en commentaire sur la durée a un format variable selon que la durée dure plus ou moins d'une seconde :
"exemple1.flac # (durée exemple1 = 66 centièmes de secondes)"
"exemple2.flac #(durée exemple2 = 1 seconde et 016 centièmes)"
quel est le format s'il y a au moins deux secondes ?
quel est le format s'il y a plus de 60 secondes ?
quel est le format s'il y a plus de 60 minutes ?
(etc. jours, mois,... on peut aller loin comme çà)
les temps d'origine sont en heures, minutes, secondes et millièmes de secondes. Dans le temps a ajouter, peut-il y avoir des millièmes aussi ? Si oui, les centièmes sont-ils alors aussi mentionnés ou la mention des millièmes remplace-t-elle celle des centièmes ?
Par curiosité, d'où vient ce fichier et c'est pour quoi faire ?
Dal
Pour l'instant je ne dispose que du temps de début, mais ai accès à la durée de chaque occurence.
La partie qui me pose le plus de problème est dans le découpage. Je sens théoriquement que je devrait me servir d'un tableau de hachage pour stocker chaque information. Mais la syntaxe exacte m'échappe. (entre autres chose) Avez vous une idée la dessus qui me permettrais d'afficher :
---------------------
1289,642 exemple1
1395,628 exemple1
1766,811 exemple2
2143,055 exemple2
---------------------
#!/usr/bin/perl use strict; use warnings; my $nom_bloc = ""; while (<DATA>) { # si ligne blanche, $nom_bloc est réinitialisé et on saute # une ligne if (/^\s*$/) { $nom_bloc = ""; print "\n"; } elsif # si nouveau bloc, conserver le nom dans $nom_bloc (/^(exemple\d+)\.flac\s+#\s*\(durée\s(exemple\d+)\s*=\s*/) { # vérifier que $1 et $2 sont égaux if ($1 eq $2) { $nom_bloc = $1; } else { print "Erreur de format ligne $_\n"; exit; } } elsif # si temps, capturer, convertir et afficher (/^(\d+):(\d+):(\d+),(\d+)$/) { # si $nom_bloc est vide, c'est qu'il y a une # erreur de format if ($nom_bloc eq "") { print "Erreur de format ligne $_, aucun bloc identifiable\n"; exit; } # $1 à $4 ont respectivement, heure, minutes, # secondes et millièmes print int(($1 * 3600) + ($2 * 60) + $3) . ",$4 $nom_bloc \n"; } # si c'est autre chose, le format est incorrect else { print "Erreur de format ligne $_, format non identifié\n"; exit; } } __DATA__ exemple1.flac # (durée exemple1 = 66 centièmes de secondes) 00:21:29,642 00:23:15,628 exemple2.flac #(durée exemple2 = 1 seconde et 016 centièmes) 00:29:26,812 00:35:43,056 00:44:37,231donne ceci :
Dal
Ce sont les regexp qui font tout le travail, l'ordre séquentiel de lecture étant suffisant pour faire ce que tu veux faire.