Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 23/12/2009, à 15:22

YvanD

[Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Salut tout le monde, big_smile

J'ai un problème, je suis en train de faire un script bash (utilisant principalement sed) qui convertisse des pages html (pas du tout valide, loin de là) en xhtml (pour la rendre valide).
Je vais essayer d'illustrer mon problème sur un exemple simple (qui est fictif).

Je souhaite transformer ce texte

Partie 1 <span style=...>...</span> Partie 2 <span style=...>...</span> Partie 3

en ceci

Partie 1  Partie 2  Partie 3

Bien sur le but de ce script n'est pas d'enlever toutes ces balises mais mon pb, c'est que la commande

echo 'Partie 1 <span style='...'>...</span> Partie 2 <span style='...'>...</span> Partie 3' | sed 's|<span.*<\/span>||g'

me renvoie :

Partie 1  Partie 3           # Oups Partie 2 a disparu !!!

« Donc .* prend le max de longueur possible » (il s'arrête au dernier trouvé)
Mais comment lui dire que non ??

J'espère avoir clair. Merci de votre aide.

Dernière modification par YvanD (Le 29/12/2009, à 18:06)

Hors ligne

#2 Le 23/12/2009, à 15:29

sputnick

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

echo 'Partie 1 <span style='...'>...</span> Partie 2 <span style='...'>...</span> Partie 3' | \
sed -r 's@</?span[^>]*>@@g'

Dernière modification par sputnick (Le 23/12/2009, à 15:33)


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#3 Le 23/12/2009, à 15:35

becket

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

 sed 's|<[^s]*span[^>]*>||g'

Hors ligne

#4 Le 23/12/2009, à 15:36

YvanD

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Un grand merci sputnick.

J'essaye de comprendre, mais je bloque sur la signification de [^>].

Hors ligne

#5 Le 23/12/2009, à 15:38

sputnick

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

tout ce qui n'est pas un >


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#6 Le 23/12/2009, à 17:18

YvanD

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

J'ai encore une question :
Je veux supprimer les balises inutiles genre <span>blabla</span> mais conserver les balises span utiles (qui ont au moins un attribut).

Je veux remplacer ça

Ceci est un <span>span inutile</span> mais voici un <span class='uneclasseqcq'>span utile</span> !

par ceci

Ceci est un span inutile mais voici un span utile !

EDIT : je pensais au métacaractère & mais je n'y arrive pas.

Dernière modification par YvanD (Le 23/12/2009, à 17:18)

Hors ligne

#7 Le 23/12/2009, à 19:12

becket

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

 sed 's|<span>\([^<]*\)<\/span>|\1|g'

Hors ligne

#8 Le 26/12/2009, à 17:20

YvanD

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Merci encore becket.

J'ai (encore) une question big_smile
Je voudrais supprimer les commentaires html.

Mais je rencontre un problème pour certains commentaires, voici un exemple de commentaire que je voudrais supprimer proprement.

<!--<xml>...-...</xml>-->

En fait le problème c'est que [^>] ne marche pas car il y des > dans <!-- --> donc il faudrait un truc du genre [^-->] mais ceci ne marche pas.
Pourriez-vous me dire la syntaxe correcte à utiliser.

EDIT : bien sur je ne veux/peux pas utiliser s|<!--.*-->||g car il y a plusieurs commentaires sur une même ligne.

Dernière modification par YvanD (Le 26/12/2009, à 17:21)

Hors ligne

#9 Le 26/12/2009, à 22:30

sputnick

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

sed 's@^[[:space:]]*<!--\(<xml>.*</xml>\)-->$@\1@'


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#10 Le 28/12/2009, à 11:38

YvanD

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Merci sputnick.

En fait dans un commentaire il peut y avoir n'importe quel balise par forcément au début et à la fin du commentaire...

Je voudrais simplement arriver à dire à sed, tu t'arrêtes dès que tu vois "-->".
J'ai essayé cette syntaxe "<!--[^-->]*-->" ça ne marche pas, ni "<!--[^\(-->\)]*-->".

Hors ligne

#11 Le 28/12/2009, à 14:19

Totor

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Bonjour,

Ce n'est pas si simple que cela car je suppose que le commentaire peut être multi-lignes. il se peut aussi qu'il y ait plusieurs commentaires sur la même ligne.
Je n'ai pas poussé mes tests mais cela devrait faire l'affaire :

sed '/<!--/ { :deb; $ b fin; s/-->/&/1; t fin; N; b deb; :fin s/-->/@/1;s/\(^<!--\)*<!--[^@]*@\(.*\)/\1\2/1; s/<!--/&/1; t deb }' fichier

la seule restriction : il ne faut pas que le caractère @ soit déjà présent dans le commentaire (ou avant). j'ai du utiliser cette astuce
EDIT :
légèrement mieux :

sed '/<!--/ { :deb; $ b fin; s/-->/&/1; t fin; N; b deb; :fin s/-->/@/1;s/<!--[^@]*@\(.*\)/\1/1; s/<!--/&/1; t deb }' fichier

chaine testée :

echo -e '<!--jklj-->dsgsdg<!--n\nnn-->  xwcv  <!--jghj-->C'|sed '/<!--/ { :deb; $ b fin; s/-->/&/1; t fin; N; b deb; :fin s/-->/@/1;s/<!--[^@]*@\(.*\)/\1/1; s/<!--/&/1; t deb }'

Dernière modification par Totor (Le 28/12/2009, à 18:43)


-- Lucid Lynx --

Hors ligne

#12 Le 28/12/2009, à 20:08

YvanD

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Ça m'a l'air très complexe.

En fait le fichier html est sur UNE seule ligne (en fait mon script fait au début « tr '\n' ' ' » (à la fin le contraire). Aurais-tu alors plus simple

Dernière modification par YvanD (Le 28/12/2009, à 20:08)

Hors ligne

#13 Le 28/12/2009, à 22:01

sputnick

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Quel est le but ultime YvanD ?
Si c'est parser proprement du XML il existe des bindings dans tous les languages de 3e génération. Perl a la magnifique : XML::Simple ... comme son nom l'indique...


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#14 Le 28/12/2009, à 22:18

sputnick

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Ce que je comprends de ta demande :
sed -r 's@<!--(.*)-->@\1@' <file>


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne

#15 Le 28/12/2009, à 23:37

Totor

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

sputnick a écrit :

Ce que je comprends de ta demande :
sed -r 's@<!--(.*)-->@\1@' <file>

là y'a pas de suppression de commentaire mais des balises commentaires.
Par ailleurs, ce n'est pas suffisant car cela supprime la toute première balise <!-- et la toute dernière balise --> (même s'il y en a d'intermédaires).

exemple :

$echo '<!--A-->B<!--C-->D<!--E-->F'|sed -r 's@<!--(.*)-->@\1@'
A-->B<!--C-->D<!--EF

alors qu'il souhaiterait obtenir l'un des résultats suivant :

1 : B<!--C-->D<!--E-->F
ou
2 : <!--A-->BD<!--E-->F
ou
3 : BDF

En tout cas, c'est ce que je comprend ... hmm

YvanD a écrit :

Je voudrais supprimer les commentaires html.

je reprend la question de sputnick : que souhaites-tu exactement ?
-- supprimer le premier commentaire (ex 1) ?
-- supprimer un commentaire parmis d'autres (ex 2) ?
-- supprimer tous les commentaires (ex 3) ?
-- supprimer les balises commentaire ?

si tu n'exprimes pas clairement ton besoin, on ne pourra pas t'aider.

Note : le tr '\n' ' ' n'est pas utile. Par ailleurs l'inverse faussera ton fichier car TOUS les blancs seront transformés en saut de ligne impliquant très probablement un changement de mise en forme, de texte...

Enfin, sed n'est pas trivial... son utilisation est-elle une contrainte ?


-- Lucid Lynx --

Hors ligne

#16 Le 29/12/2009, à 11:16

YvanD

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Merci de votre aide.

Explications :
Je souhaite convertir « à la main » (avec bash et sed) un fichier html truffé d'erreur (réalisé jadis avec un logiciel sous Windobe©), je souhaite donc les corriger avec mon script (il est déjà bien avancé et fonctionne plutôt pas mal mais il reste quelques améliorations).
D'abord le script fait un « tr '\n' '%' » (et « tr '\r' '%' » [le fichier contient des \n et des \r] et même « iconv ... » [pour convertir les caractères en UTF8]) donc tout est ramené sur une seule ligne, ensuite il exécute un script sed avec « sed -r -f nom_du_script » et rétablit les retours à la ligne avec « tr '%' '\n' ».

Je souhaite en ce moment supprimé tous les commentaires (donc les balises commentaires) mais il y a des contraintes :
  * comme tout est sur une seule ligne, il peut y avoir plusieurs commentaires donc la syntaxe « s|<!--.*-->||g » ne convient pas (par ex « 1<!--2-->3<!--4-->5 » deviendra « 15 » et non pas « 135 que je voudrais » !!),
  * de plus le commentaire peut contenir des balises html (xml) donc la syntaxe suivante ne convient pas non plus : « s|<!--[^>]*-->||g » (car par ex : « <!-- 1<b>2</b> 3--> » ne se suppr correctement !!).

Donc voici un exemple concret je souhaite transformer ceci

<!--blabla1--> blabla2 <!-- bla<qcq>bla</qcq>--> blabla3

en ceci

 blabla2  blabla3

Hors ligne

#17 Le 29/12/2009, à 12:23

Totor

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Puisque tu tiens à n'avoir q'une seule ligne :

sed 's/-->/@/g; :deb ; s/<!--[^@]*@\(.*\)/\1/1; s/<!--/&/1; t deb'

Dernière modification par Totor (Le 29/12/2009, à 12:25)


-- Lucid Lynx --

Hors ligne

#18 Le 29/12/2009, à 15:41

YvanD

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Je pense que mon seul pb est la syntaxe correcte pour dire à sed de s'arrêter à la prochaine expression (notamment dans mon cas : « --> »).

Je connais la syntaxe pour dire de s'arrêter au prochain caractère ("<!--[^>]*-->", mais comme je l'ai dit cela ne me convient pas).

Dernière modification par YvanD (Le 29/12/2009, à 15:41)

Hors ligne

#19 Le 29/12/2009, à 18:05

YvanD

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Désolé je n'avais pas vu ton post Totor, merci.
Je n'avais pas penser à réduire --> à un seul caractère pour contourner mon problème !

Si quelqu'un à mieux... en attendant je met en résolu.

Dernière modification par YvanD (Le 29/12/2009, à 18:06)

Hors ligne

#20 Le 29/12/2009, à 19:04

Balkoth

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Version qui fonctionne même si le commentaire contient des @ :

sed -r 's/<!--([^-]|-[^-]|--[^->])*-+->//g'

Hors ligne

#21 Le 30/12/2009, à 23:06

Pylades

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Pour réduire le fichier à une ligne, voici une commande fonctionnant même si le fichier source contient un % :
[code]sed 's/$/


“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
                Linus Torvalds – 12 janvier 2003

Hors ligne

#22 Le 30/12/2009, à 23:09

Pylades

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Deuxième essai :


Pour réduire le fichier à une ligne, voici une commande fonctionnant même si le fichier source contient un % :

sed 's/$/le-caractère-unicode-F0000/g' | tr '\n' ' '

# Pour remettre les nouvelles lignes :
sed 's/le-caractère-unicode-F0000-suivit-d-un-espace/\n/g'

Ensuite, pour tes commentaires :

sed -r 's/<!--[^\(->\)]*->//g'

“Any if-statement is a goto. As are all structured loops.
“And sometimes structure is good. When it’s good, you should use it.
“And sometimes structure is _bad_, and gets into the way, and using a goto is just much clearer.”
                Linus Torvalds – 12 janvier 2003

Hors ligne

#23 Le 30/12/2009, à 23:51

Totor

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Paul0102 a écrit :
sed -r 's/<!--[^\(->\)]*->//g'

Merci, je note !
smile (je passerai cette fin d'année moins bête wink)


-- Lucid Lynx --

Hors ligne

#24 Le 31/12/2009, à 11:00

YvanD

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

Avec la méthode de Paul0102 ceci ne marche pas avec mon ex (plus haut) :

echo '<!--blabla1--> blabla2 <!-- bla<qcq>bla</qcq>--> blabla3' | sed -r 's/<!--[^\(->\)]*->//g'

Pourquoi ceci

sed -r 's/<!--[^\(->\)]*->//g'

alors qu'un commentaire (x)html se termine par « --> » et non pas « -> » ?

Enfin pourquoi avec --> ceci ne marche pas, ex :

$ echo '<!--blabla1--> blabla2 <!-- bla<qcq>bla</qcq>--> blabla3' | sed -r 's/<!--[^\(-->\)]*-->//g'
sed: -e expression n°1, caractère 23: Fin d'intervalle invalide

Dernière modification par YvanD (Le 31/12/2009, à 11:01)

Hors ligne

#25 Le 31/12/2009, à 12:20

sputnick

Re : [Résolu] Sed : comment s'arrêter à la 1ère expression trouvée

C'est quoi le bins avec [^\(-->\)] ? ( Traduction en language humain si possible... )


On ne peut pas mettre d'array dans un string!
https://sputnick.fr/

Hors ligne