|
|
|
|
Bonjour,
je developpe un petit script qui enleve les commentaires d'un fichier C.
Tout va bien sauf pour les commentaires du type :
/* ======================
blabla
blabla
blabla
=======================*/
Pour les supprimer, j'ai voulu supprimer les sauts de lignes pour pouvoir ensuite enlever ce qui se trouve entre /* et */
Ca donne :
tr '\r\n' '~' |
sed 's/\/\*.*\*\///g' |
tr '~' '\r\n'
Le hic, c'est que le sed en question prend comme balise la 1° occurence de /* et la derniere de */
donc ca ne marche pas pour du code C de la forme
toto=0;
/* ======================
blabla
blabla
blabla
=======================*/
toto=1;
/* comment */
toto=2;
Resultat obtenu :
toto=0;
toto=2;
Quelqu'un sait il comment faire ?
N'hésitez pas si vous avez besoin d'explication supplémentaires!
Merci d'avance,
Christophe
Une fois de plus, merci jicipy !
|
$ cat plop
toto=0;
/* ======================
blabla
blabla
blabla
=======================*/
toto=0; /* commentaire
blabla
blabla
blabla
sur plusieurs lignes */
toto=1;
/* comment */
toto=2;
$ sed -e 's!/\*.*\*/!!' -e '/;[ ]*\/\*/{:z; N; s!/\*.*\*/!!;Tz}' -e'/\/\*/,/\*\//d' plop
toto=0;
toto=0;
toto=1;
toto=2;;-))
Z'@+...che. JP : Zen, my Nuggets ! ;-) Le savoir n'est bon que s'il est partagé. |
Merci encore !
|
Merci !! Ca m'a l'air de bien marcher !!
|
Voilà les explications des différentes parties juste pour la forme, parce qu'avec les nouvelles directives, la simple expression : sed -e '/.*\/\*/{:z; N; s!/\*.*\*/!!;Tz}'suffit pour tous les cas ;-))
En fait on recherche un motif correspondant à "/*bla ... bla... bla ... */" d'abord sur une ligne entière (les délimiteurs commençant et finissant la ligne), puis on examine le cas ou le 1er délimiteur ne serait pas le 1 er caractère sur la ligne et que le délimiteur de fin ne serait pas sur la même ligne. En dernier lieu vient le cas où les commentaires sont sur plusieurs ligne avec un délimiteur de départ en début de ligne... s!/\*.*\*/!!
# sur une ligne on supprime tout
/.*\/\*/ {
# sur plusieurs lignes ( matche aussi le cas sur un seule ligne) mais ne commençant pas en début de ligne. Si une ligne comprenant le motif est trouvée on enchaine les commandes se trouvant entre accolades
:z
# définition d'une étiquette pour boucler
N
# donc si un motif est trouvé, on ajoute la ligne suivante dans l'espace de travail
s!/\*.*\*/!!
# on supprime tout entre /* et */ si le motif est présent
T z
# on teste si une substitution a eu lieu au cas ou le motif serait présent dans l'espace de travail. Dans le cas contraire on boucle en se branchant à l'étiquette et ainsi de suite jusqu'à ce qu'une substitution ait lieu, ce qui aura pour effet de lancer la commande qui suit l'accolade fermante
}
/\/\*/,/\*\// d
#si un motif correspondant se situe sur plusieurs lignes, on efface toutes les lignes de cet intervalle
PS. le motif : /;*[ ]*\/\*/correspondait à : un motif ne commençant pas en début de ligne, après un point virgule suivi éventuellement d'un (ou plusieurs) espace(s)... ;-)) Z'@+...che. JP : Zen, my Nuggets ! ;-) Le savoir n'est bon que s'il est partagé. |
Allez un ch'tit dernier pour la route et pour que ce soit bien propre (le dernier laisser plein de lignes vides inutiles).
$ cat plop toto=0; /* ====================== blabla blabla blabla =======================*/ toto=1; /* commentaire blabla blabla blabla sur plusieurs lignes */ #define ONE 1 /* ceci est un commentaire sur plusieurs lignes */ toto=2; /* comment */ toto=3;La version sale : $ sed -e '/.*\/\*/{:z; N; s!/\*.*\*/!!;Tz}' plop
toto=0;
toto=1;
#define ONE 1
toto=2;
toto=3;Et la version proprette :$ sed -e '/.*\/\*/{:z; N; s!/\*.*\*/!!;Tz; /^$/{N;/^\n$/d}}' plop
toto=0;
toto=1;
#define ONE 1
toto=2;
toto=3;;-))
Z'@+...che. JP : Zen, my Nuggets ! ;-) Le savoir n'est bon que s'il est partagé. |