Substitution avec sed

Fermé
romzzzz - 6 août 2010 à 09:57
 romzzzz - 6 août 2010 à 16:21
Bonjour,

dans un fichier source c, je dois récupérer un bloc de texte bien particulier (qui est en fait un prototype de fonction). Ce bloc de texte est délimité à droite par un point virgule et à gauche par un point virgule ou un { ou les deux caractères */ (étoile slash). Enfin il comprend à l'intérieur le nombre x.

sed peut faire la substitution mais ce qui me gène c'est la prise en compte du "ou" pour les caractères limitant à gauche et surtout le fait de préciser que le nombre x doit être inclus dans ce bloc.

Merci !

11 réponses

jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
6 août 2010 à 10:07
Salut,

Merci de poster un exemple CONCRET afin de dissiper les malentendus ;-))
0
Voilà par exemple un extrait du fichier c :
.....
.....
.....

***************************************************************/

admn_ano_ ( (message_struct_def *)msg_sco_p,
(context_struct_def *)ctx_glob_p, (u16)1250,
(s16)nouvel_etat );
....
....

****************/

admn_em_ano ( (id_classe_t)VAL_IRT_FCT_PADMN,
ANO_NON_SIGNIFICATIVE,
(u32) 0, (u16)1990,
(u16) 0,
(u8*) NULL,
(u16) 0,
(u8*) NULL,
(u16) 0,
(u8*) NULL );

.....
.....

Je dois récupérer les prototypes des deux fonctions (ie du nom jusqu'à la dernière parenthèse fermante).
Ici les fonctions sont délimitées à droite par un */ (mais cela peut être un { ou un point virgule) et elles contiennent le nombre 1250 pour l'une et 1990 pour l'autre.
Ce sont en effet les seuls points communs que possèdent toutes ces fonctions.

J'espère que c'est plus clair ?
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
6 août 2010 à 10:33
Oui et non ;-\

Mets un peu plus de code avec ce que tu veux récupérer en gras et avec des exemples contenants toutes les possibilités du OU "), */, {, ;".

Merci
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
6 août 2010 à 10:35
Salut,

sed c'est obligatoire?
0
Non pas du tout, c'est juste ce qui me semble le plus adapte !
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
6 août 2010 à 10:37
Salut,

Non, mais ça devrait ;-)))
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
.....
.....
.....

***************************************************************/

admn_ano_ ( (message_struct_def *)msg_sco_p,
(context_struct_def *)ctx_glob_p, (u16)1250,
(s16)nouvel_etat )
;
....
....

****************/

admn_em_ano ( (id_classe_t)VAL_IRT_FCT_PADMN,
ANO_NON_SIGNIFICATIVE,
(u32) 0, (u16)1990,
(u16) 0,
(u8*) NULL,
(u16) 0,
(u8*) NULL,
(u16) 0,
(u8*) NULL )
;

.....
.....
{
admn_an2_ine (
(context_struct_def *)ctx_glob_p, (u16)1786,
(s16)nouvel_etat)
;

....
.....
......;
admn_em_anolog ( (id_classe_t) VAL_IRT_FCT_PADMN,
(u32) 0, (u16)235,
(u16) admn_lg_msg)
;


?
0
Le nom des fonctions, le nombre d'arguments et le type des arguments ne sont jamais les même, mais il y a toujours un nombre à l'intérieur. Elles peuvent être sur une ou plusieurs lignes.
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
6 août 2010 à 10:46
Et un peu du reste du code, ce n'est pas possible ?

Toutes les fonctions à récupérer commencent par "admn_" ?
Ou non ?
Il y a d'autres fonctions qui commencent par ça et qu'il ne faut pas récupérer ?

Désolé d'être aussi tétu, mais bien souvent on se casse la tête pour satisfaire la demande et ensuite on vient nous dire, mais si il y a ça, ou ça, mais je ne veux pas ça, ça ne marche pas parce que...

;-\
0
:) pas de problème !

Non justement il n'y a aucune ressemblance dans le nom ou la syntaxe de ces fonctions excepte la présence d'un nombre en argument. Il peut y avoir d'autres fonctions dont le nom commence par la même chose. Il doit y avoir plus de 10000 fichiers source...
Les seuls points qui les différencient sont ceux que j'ai cités !
Pour le reste du code j'aimerai éviter si possible, je n'en ai pas le droit. Mais c'est du code c normal.

J'espère que ca suffira !
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
6 août 2010 à 11:17
Je propose un autre raisonnement pour ça.
Il n'y a pas de { dans le prototype (la déclaration) de la fonction, mais dans la définition de la fonction

Vu que le prototype d'une fonction commence avec le nom de la fonction et qu'il y a des règles de nommage pour le nom de la fonction (commence avec une lettre et peux contenir des chiffres et underscore) suivi ou pas d'espace ensuite une parenthèse ouvrante et puis les paramètres et puis espaces ou pas et à la fin parenthèse fermante suivi de ;

Ce qui donnera la recherche de paragraphe ou ligne (je n'ai pas testé)

Pour ligne
/^[a-zA-Z][a-zA-Z0-9_]\s+\([a-zA-Z0-9_,\s]*\)\s* ;/

Pour paragraphe

/^[a-zA-Z][a-zA-Z0-9_]\s+/ .. /\)\s* ;/
0
Le problème c'est que je ne veux que les fonctions qui contiennent mon nombre en argument, parce qu'il existe des milliers d'autres prototypes dans mes fichiers.

Merci pour l'aide quand même.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
6 août 2010 à 11:36
Re,

Quel nombre?
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
6 août 2010 à 11:38
et elles contiennent le nombre 1250 pour l'une et 1990 pour l'autre.
Ce sont en effet les seuls points communs que possèdent toutes ces fonctions.
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
6 août 2010 à 11:46
Re,

Ah, ok.
Mais je te laisse continuer avec sed ;-)
Quoi que pour moi quand je vois ça "de problème avec sed sous Solaris je pense " je pense qu'avec perl c'est mieux ;-)))
0
Oui je réalise ca maintenant mais j'ai déjà écrit 160 lignes en shell script... Je vais devoir passer au Perl je pense, surtout pour les problèmes d'interfaçage qui arrivent !
:)
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
6 août 2010 à 11:20
Essaye ça (test effectué sur l'exemple du post #7) :

$ sed -n '/.* (/{:z;N;/);$/!bz;/1250\|1990/p}' romzz
admn_ano_ ( (message_struct_def *)msg_sco_p,
(context_struct_def *)ctx_glob_p, (u16)1250,
(s16)nouvel_etat );
admn_em_ano ( (id_classe_t)VAL_IRT_FCT_PADMN,
ANO_NON_SIGNIFICATIVE,
(u32) 0, (u16)1990,
(u16) 0,
(u8*) NULL,
(u16) 0,
(u8*) NULL,
(u16) 0,
(u8*) NULL );
0
C'est exactement ca que je voudrais, mais encore (tu m'avais déjà conseille sur sed la dernière fois) un @#&!!%$ de problème avec sed sous Solaris je pense :

sed -n '/.* (/{:z;N;/);$/!bz;/1250\|1990/p}' padmn.c > resultpad
bz: Event not found.

C'est assez chiant ca...

En tout cas merci beaucoup, je vais essayer de traduire ca en sed Solaris...
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
6 août 2010 à 11:32
Essaye comme ça :

sed -n '
/.* (/{
:z
N
/);$/!bz
/1250\|1990/p
}
' fichier
0
J'ai mis ca dans un script (dans une console je ne vois pas comment faire) et ca enlève le message d'erreur mais le fichier de résultat est vide.

Il doit y avoir une syntaxe particulière pour le "bz"...

PS : les nombres 1250 et 1990 c'était pour l'exemple, elles contiennent en fait toute un nombre qui peut prendre n'importe quelle valeur suivant la fonction (unicité). Le but final étant de placer une variable shell script à la place de ce nombre dans la commande sed pour pouvoir récupérer la fonction que je veux dans tout le code.
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 897
6 août 2010 à 11:50
dans une console je ne vois pas comment faire

C'est simple :

sed -n ' <Entrée>
/.* (/{ <Entrée>
:z <Entrée>
N <Entrée>
/);$/! bz <Entrée>
/1250\|1990/p <Entrée>
} <Entrée>
' fichier <Entrée>


Rajoute un espace entre le "!" et "bz" pour voir... sans garantie ;-\
0
~/Documents>sed -n '
Unmatched '.
~/Documents>/.* (/{
Too many ('s.
~/Documents>:z
:z: Command not found.
~/Documents>N
N: Command not found.

Je ne pense pas que je vais continuer :)
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
Modifié par lami20j le 6/08/2010 à 12:20
Re,

~ $ cat c.c 
Voilà par exemple un extrait du fichier c : 




***************************************************************/ 

admn_ano_ ( (message_struct_def *)msg_sco_p, 
(context_struct_def *)ctx_glob_p, (u16)1250, 
(s16)nouvel_etat ); 



****************/ 

admn_em_ano ( (id_classe_t)VAL_IRT_FCT_PADMN, 
ANO_NON_SIGNIFICATIVE, 
(u32) 0, (u16)1990, 
(u16) 0, 
(u8*) NULL, 
(u16) 0, 
(u8*) NULL, 
(u16) 0, 
(u8*) NULL ); 

***************************************************************/ 


~ $ awk 'BEGIN { RS = ""  } /[a-zA-Z_] \(.*1250|1990/ , /).*;/' c.c 
admn_ano_ ( (message_struct_def *)msg_sco_p, 
(context_struct_def *)ctx_glob_p, (u16)1250, 
(s16)nouvel_etat ); 
admn_em_ano ( (id_classe_t)VAL_IRT_FCT_PADMN, 
ANO_NON_SIGNIFICATIVE, 
(u32) 0, (u16)1990, 
(u16) 0, 
(u8*) NULL, 
(u16) 0, 
(u8*) NULL, 
(u16) 0, 
(u8*) NULL );

--
GNU/Linux:Linux is Not Ubuntu! Quel linux choisir ne veut pas dire votre Distribution préférée,
106485010510997108
0
Effectivement je crois qu'avec awk il n'y a pas ces problèmes sous Solaris, cependant :

~/Documents>awk 'BEGIN { RS = "" } /[a-zA-Z_] \(.*1250|1990/ , /).*;/' padmn.c
awk: syntax error near line 1
awk: bailing out near line 1

Désolé :(

PS : et pour un seul nombre par exemple 1250 au lieu de (1250|1990) ?
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
6 août 2010 à 14:23
Re,

Essai avec nawk
0
~/Documents>nawk 'BEGIN { RS = "" } /[a-zA-Z_] \(.*1250|1990/ , /).*;/' padmn.c
nawk: illegal primary in regular expression ).*; at .*;
source line number 1
context is
BEGIN { RS = "" } /[a-zA-Z_] \(.*1250|1990/ , >>> /).*;/ <<<

Je t'ai dit tu peux surement faciliter l'expression en ne recherchant qu'un seul nombre parmi les deux !
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
6 août 2010 à 14:33
Re,

Je t'ai dit tu peux surement faciliter l'expression en ne recherchant qu'un seul nombre parmi les deux !

Oui.
Ben, si ça marche tant mieux pour toi, mais as-tu testé?
0
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
6 août 2010 à 14:45
Re,

Et si tu groupes les nombres (sinon tu seras obligé de faire une boucle pour chaque nombre ou trouver la syntaxe correcte de la regex) ?

awk 'BEGIN { RS = "" } /[a-zA-Z_] \(.*(1250|1990)/ , /).*;/' padmn.c 
0