J'ai fini par mettre un peu de perl et de tr.
ça se passe en deux phases :
- suppression de tous les retours chariot, ce qui a pour effet de mettre tout le fichier sur une seule ligne, mais aussi et surtout de recoller les lignes coupées qui m'intéressent. Cette étape est faite avec un simple tr -d '\n'
- ajout de retours chariot avant <balise> et après </balise> pour isoler les lignes que je veux récupérer. Cette fois, c'est du perl. J'ai essayé avec sed, mais sous aix, impossible de lui faire insérer un retour chariot. Le \n n'est pas interprété, le \x0A non plus. Si quelqu'un a une explication, ça m'intéresse.
Le code perl est simple (je découvre complètement perl, c'est sûrement très moche) :
perl -e 'while(<>){s/(<balise>)([^<]+)(</balise>)/\n2円\n/g;print;}'
Oui, je sais c'est idiot, c'est exactement ce pour quoi sed est fait, mais comme dit plus haut, je n'ai pas réussi à lui faire écrire des retours chariot sous aix.
La commande de substitution se décompose comme ceci :
- <balise> : bah, on recherche la chaine de caractères telle quelle
- [^<]+ : un ou plusieurs caractères, n'importe lequel sauf "<". Ici, j'aurais pu mettre .*, mais dans ce cas, perl cherche à faire la plus grande chaine qui matche. Je me retrouverais donc avec une chaine commençant par la première occurrence de "<balise>" du fichier et finissant par la dernière occurrence de "</balise>", ce qui ne fonctionnerait que si le fichier en entrée ne contient qu'une et une seule fois la balise en question (ce qui n'est bien sûr pas le cas).
- </balise> : comme le premier bloc, on recherche la chaine de caractères telle quelle.
On substitue ce qui matche par "\n2円\n", c'est à dire deux retours chariot encadrant le deuxième bloc dans la chaine qui matche le pattern. Comme ça, d'un coup, je supprime les balise pour ne récupérer que le contenu, isolé sur une ligne.
La suite du traitement est un grep sur une chaine que je retrouve uniquement dans les lignes qui m'intéressent, suivi d'un awk qui saucissonne le contenu et me le crache sous forme de sql que je peux jouer directement.
Tout ça manque certainement d'élégance (par exemple, dans la substitution, je peux sûrement me passer des parenthèses autour de "<balise>" et "</balise>", vu que je ne les réutilise pas dans la chaine de substitution...), j'aurais bien voulu du coup intégrer le tr et le grep au perl, mais ça dépasse mes compétences dans ce langage...
Encore une fois, si vous avez des idées sur le sujet...
# pb résolu, merci à vos idées qui m'ont été utiles
Posté par mortimer . En réponse au message regex de recherche de lignes coupées. Évalué à 0.
J'ai fini par mettre un peu de perl et de tr.
ça se passe en deux phases :
- suppression de tous les retours chariot, ce qui a pour effet de mettre tout le fichier sur une seule ligne, mais aussi et surtout de recoller les lignes coupées qui m'intéressent. Cette étape est faite avec un simple tr -d '\n'
- ajout de retours chariot avant <balise> et après </balise> pour isoler les lignes que je veux récupérer. Cette fois, c'est du perl. J'ai essayé avec sed, mais sous aix, impossible de lui faire insérer un retour chariot. Le \n n'est pas interprété, le \x0A non plus. Si quelqu'un a une explication, ça m'intéresse.
Le code perl est simple (je découvre complètement perl, c'est sûrement très moche) :
perl -e 'while(<>){s/(<balise>)([^<]+)(</balise>)/\n2円\n/g;print;}'
Oui, je sais c'est idiot, c'est exactement ce pour quoi sed est fait, mais comme dit plus haut, je n'ai pas réussi à lui faire écrire des retours chariot sous aix.
La commande de substitution se décompose comme ceci :
- <balise> : bah, on recherche la chaine de caractères telle quelle
- [^<]+ : un ou plusieurs caractères, n'importe lequel sauf "<". Ici, j'aurais pu mettre .*, mais dans ce cas, perl cherche à faire la plus grande chaine qui matche. Je me retrouverais donc avec une chaine commençant par la première occurrence de "<balise>" du fichier et finissant par la dernière occurrence de "</balise>", ce qui ne fonctionnerait que si le fichier en entrée ne contient qu'une et une seule fois la balise en question (ce qui n'est bien sûr pas le cas).
- </balise> : comme le premier bloc, on recherche la chaine de caractères telle quelle.
On substitue ce qui matche par "\n2円\n", c'est à dire deux retours chariot encadrant le deuxième bloc dans la chaine qui matche le pattern. Comme ça, d'un coup, je supprime les balise pour ne récupérer que le contenu, isolé sur une ligne.
La suite du traitement est un grep sur une chaine que je retrouve uniquement dans les lignes qui m'intéressent, suivi d'un awk qui saucissonne le contenu et me le crache sous forme de sql que je peux jouer directement.
Tout ça manque certainement d'élégance (par exemple, dans la substitution, je peux sûrement me passer des parenthèses autour de "<balise>" et "</balise>", vu que je ne les réutilise pas dans la chaine de substitution...), j'aurais bien voulu du coup intégrer le tr et le grep au perl, mais ça dépasse mes compétences dans ce langage...
Encore une fois, si vous avez des idées sur le sujet...