[sed et Cie] Formater un fichier csv en xml

[Résolu/Fermé]
Signaler
Messages postés
1956
Date d'inscription
samedi 22 novembre 2008
Statut
Membre
Dernière intervention
27 juillet 2016
-
Messages postés
1956
Date d'inscription
samedi 22 novembre 2008
Statut
Membre
Dernière intervention
27 juillet 2016
-
Hello,
(Précision : je tourne sous Ubuntu 16.04)

J'ai un fichier foo.txt avec plein de lignes comme ça :
10_2719,P11,1025.5,489.5
10_2719,P14,2883.5,6927.5
10_2720,P10,1456,305
10_2720,P11,753.5,061.5
11_2720,P14,2741.5,1703
11_2721,P5,1313,813
...


La première colonne représente le nom d'une image.
La seconde un identifiant d'un point dans cette image.
La troisième une coordonnée selon l’abscisse dans cette image, et la dernière une coordonnée selon l'ordonnée.

Dans un seul fichier bar.txt, je souhaiterais pour chaque image, obtenir un bloc structuré comme suit (exemple pour la 1ère image) :
    <Bloc>
<NomImage> 11_2719.JPG </NomImage>
<Point>
<NomPoint> Point11 </NomPoint>
<Coordonnee1Cart> 1025.5 489.5 </Coordonnee1Cart>
</Point>
<Point>
<NomPoint> Point14 </NomPoint>
<Coordonnee1Cart> 2883.5 6927.5 </Coordonnee1Cart>
</Point>
</Bloc>
...


Et ainsi de suite pour toutes les autres images.
Il y a une nombre variable de point par image et certains se retrouvent parfois dans plusieurs images.

J'aimerais faire ça avec "sed" mais je coince au stade où il faudrait en fait ne traiter qu'une seule fois le nom de l'image (1ère occurrence) pour l'inclure entre les balises <NomImage> et </NomImage>.

· Version "simple" les lignes se suivent par blocs d'images croissants comme dans l'exemple ici.
· Version "compliquée" les lignes ne se suivent pas du tout par blocs d'images croissants, par ex. :
11_2720,P14,2741.5,1703
10_2720,P10,1456,305
10_2719,P14,2883.5,6927.5
11_2721,P5,1313,813
10_2719,P11,1025.5,489.5
10_2720,P11,753.5,061.5
...


Merci de votre aide précieuse.

Et une belle soirée !

2 réponses

Messages postés
18302
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
23 octobre 2021
5 411
hello
$ awk -f f3.awk foo.txt
<Bloc>
<NomImage> 10_2719.JPG </NomImage>
<Point>
<NomPoint> Point11 </NomPoint>
<Coordonnee1Cart> 1025.5 489.5 </Coordonnee1Cart>
</Point>
<Point>
<NomPoint> Point14 </NomPoint>
<Coordonnee1Cart> 2883.5 6927.5 </Coordonnee1Cart>
</Point>
<NomImage> 10_2720.JPG </NomImage>
<Point>
<NomPoint> Point10 </NomPoint>
<Coordonnee1Cart> 1456 305 </Coordonnee1Cart>
</Point>
<Point>
<NomPoint> Point11 </NomPoint>
<Coordonnee1Cart> 753.5 061.5 </Coordonnee1Cart>
</Point>
<NomImage> 11_2720.JPG </NomImage>
<Point>
<NomPoint> Point14 </NomPoint>
<Coordonnee1Cart> 2741.5 1703 </Coordonnee1Cart>
</Point>
<NomImage> 11_2721.JPG </NomImage>
<Point>
<NomPoint> Point5 </NomPoint>
<Coordonnee1Cart> 1313 813 </Coordonnee1Cart>
</Point>
</Bloc>
$ cat f3.awk
BEGIN {FS=","; print "<Bloc>"}
!t[$1]++ {print "\t<NomImage> " $1 ".JPG </NomImage>"}
{sub("P", "", $2); print "\t<Point>\n\t\t<NomPoint> Point" $2 " </NomPoint>\n\t\t<Coordonnee1Cart> " $3 " " $4 " </Coordonnee1Cart>\n\t</Point>"}
END {print "</Bloc>"}
2
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 41713 internautes nous ont dit merci ce mois-ci

Messages postés
1956
Date d'inscription
samedi 22 novembre 2008
Statut
Membre
Dernière intervention
27 juillet 2016
104
Bien le bonsoir.
:)

Merci infiniment pour ta réponse, t'es un chef !
Il y a juste la petite subtilité suivante en fait (celle que je n'arrive pas résoudre) :
<Bloc>
<NomImage> 10_2719.JPG </NomImage>
suivi de la liste de tous les points de l'image 2718
</Bloc>
<Bloc>
<NomImage> 10_2720.JPG </NomImage>
suivi de la liste de tous les points de l'image 2720
</Bloc>
<Bloc>
<NomImage> 11_2721.JPG </NomImage>
suivi de la liste de tous les points de l'image 2721
</Bloc>


Le contenu du reste de l'arborescence est tout bon, mais je n'arrive pas à faire en sorte que chaque image et sa suite de points soit incluse dans un <bloc> </bloc>.
Ce ne doit pas être un unique <bloc> pour toutes les images, c'est vraiment un par image.

En modifiant le début de la seconde ligne du fichier f3.awk comme ça (cette solution est un peu bancale, il est vrai) :
!t[$1]++ {print  "</bloc>\n\t<bloc>\t<NomImage> . . . . 


ça joue, sauf que je me retrouve en tout début de fichier avec une et une seule balise de fermeture </bloc> inutile. Mais c'est seulement en début, avant le tout premier <bloc>.
:/


--
"Si vous ne pouvez expliquer un concept à un enfant de six ans, c'est que vous ne le comprenez pas complètement."  -A. Einsten-
Messages postés
18302
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
23 octobre 2021
5 411
un bloc par image
avec un test if(n++)print "</Bloc>"; pour éviter un /Bloc avant la 1ère image
$ awk -f f3.awk foo.txt
<Bloc>
<NomImage> 10_2719.JPG </NomImage>
<Point>
<NomPoint> Point11 </NomPoint>
<Coordonnee1Cart> 1025.5 489.5 </Coordonnee1Cart>
</Point>
<Point>
<NomPoint> Point14 </NomPoint>
<Coordonnee1Cart> 2883.5 6927.5 </Coordonnee1Cart>
</Point>
</Bloc>
<Bloc>
<NomImage> 10_2720.JPG </NomImage>
<Point>
<NomPoint> Point10 </NomPoint>
<Coordonnee1Cart> 1456 305 </Coordonnee1Cart>
</Point>
<Point>
<NomPoint> Point11 </NomPoint>
<Coordonnee1Cart> 753.5 061.5 </Coordonnee1Cart>
</Point>
</Bloc>
<Bloc>
<NomImage> 11_2720.JPG </NomImage>
<Point>
<NomPoint> Point14 </NomPoint>
<Coordonnee1Cart> 2741.5 1703 </Coordonnee1Cart>
</Point>
</Bloc>
<Bloc>
<NomImage> 11_2721.JPG </NomImage>
<Point>
<NomPoint> Point5 </NomPoint>
<Coordonnee1Cart> 1313 813 </Coordonnee1Cart>
</Point>
</Bloc>
$
$ head f3.awk
BEGIN {FS=","}
!t[$1]++ {if(n++)print "</Bloc>"; print "<Bloc>\n\t<NomImage> " $1 ".JPG </NomImage>"}
{sub("P", "", $2); print "\t<Point>\n\t\t<NomPoint> Point" $2 " </NomPoint>\n\t\t<Coordonnee1Cart> " $3 " " $4 " </Coordonnee1Cart>\n\t</Point>"}
END {print "</Bloc>"}
Messages postés
1956
Date d'inscription
samedi 22 novembre 2008
Statut
Membre
Dernière intervention
27 juillet 2016
104
Joli, ça a l'air de bien fonctionner là !
Merci infiniment !!