[shell] Creation d'un fichier de references croisees
16 réponses
Sébastien Kirche
Bonjour aux grands gourous du shell :)
Soit un ensemble de fichiers .c d'un projet conséquent (+ de 500).
Certains de ces fichiers appellent un ensemble de fonctions maison dont le
nom commence toujours par la forme "CB_" et dont les arguments comportent
au moins 2 arguments (le premier est un pointeur - on s'en tamponne, mais
le second est un define que j'essaie de récupérer dans mon xref)
Je m'explique un peu plus en détail :
j'essaie de fabriquer un fichier texte contenant la liste des modules c
faisant ces appels l'aide de grep.
Et pour chaque fichier trouvé, j'aimerais la liste des fonctions cb_qqchose
appelées avec leurs paramètres : encore un grep
Et j'aimerais établir une liste du 2ème paramètre de mes fonctions
cb_qqchose avec les liste des fichiers où il se trouve et si possible la
ligne...
Je me débrouille en shell en général, mais je suis débutant en sed/awk qui
me semblent indiqués pour la tâche.
En plus les fichiers sources sont encodés pour mac, ce qui complique encore
un peu la tâche.
J'ai commencé un script shell, mais j'ai déjà un problème pour obtenir les
fonctions cb_qqchose : j'ai des faux positifs...
Voici mon embryon de script qui cafouille déjà:
-------------------------
#! /bin/bash
Je ne comprend pas les lignes "if" ni les "failcberr..." moi je voudrais
juste l'appel CB_LockFile(...) ou CB_Acces(...) --> problème de regexp avec
awk ?
Pour le problème d'établir une référence croisée sur les paramètres (qui
peut être le 2ème ou le 3ème) si je procède par grep successif, comment je
peux concaténer une liste à une autre ?
J'aimerais bien un peu d'aide.
Si je me fourvoie sur le langage adopté, le problème est que je ne connais
pas perl ni python ni... à la rigueur je peux prendre une solution en
emacs-lisp :)
J'ai bien le "advanced bash scripting" mais il ne m'a pas aidé pour cet
usage un peu plus pointu de awk, ni pour les listes.
PS: je me tamponne de la portabilité, il s'agit ici de remplir une tâche
ponctuelle sur ma machine. Par contre si on me suggère tcsh ou un autre à
la place de bash, je suis ouvert.
NR et FNR, ça compte le numéro du record. Pour avoir le numéro de la ligne, if faut compter le nombre de CR. Pour ça, on utilise gsub (qui renvoie le nombre de substitutions faites). c'est "n" qui contient le numéro de la ligne (on l'initialise à 1 pour chaque nouveau fichier (quand FNR == 1)).
RS=[()], ben c'est '(' ou ')'. Comme ça, vu qu'un CB_ est toujours suivi d'un '(' puis de ses arguments (y compris le deuxième, qu'on veut), puis d'un ')', on est sur qu'il ne peut pas y avoir deux CB_ dans un même record et que le record suivant un record qui contient CB_ contient son deuxième arguments (en supposant qu'il n'y ait pas de parenthèses dans les arguments de CB_...) et pas de CB_.
NR et FNR, ça compte le numéro du record. Pour avoir le numéro
de la ligne, if faut compter le nombre de CR. Pour ça, on
utilise gsub (qui renvoie le nombre de substitutions faites).
c'est "n" qui contient le numéro de la ligne (on l'initialise à
1 pour chaque nouveau fichier (quand FNR == 1)).
RS=[()], ben c'est '(' ou ')'. Comme ça, vu qu'un CB_ est
toujours suivi d'un '(' puis de ses arguments (y compris le
deuxième, qu'on veut), puis d'un ')', on est sur qu'il ne peut
pas y avoir deux CB_ dans un même record et que le record
suivant un record qui contient CB_ contient son deuxième
arguments (en supposant qu'il n'y ait pas de parenthèses dans
les arguments de CB_...) et pas de CB_.
NR et FNR, ça compte le numéro du record. Pour avoir le numéro de la ligne, if faut compter le nombre de CR. Pour ça, on utilise gsub (qui renvoie le nombre de substitutions faites). c'est "n" qui contient le numéro de la ligne (on l'initialise à 1 pour chaque nouveau fichier (quand FNR == 1)).
RS=[()], ben c'est '(' ou ')'. Comme ça, vu qu'un CB_ est toujours suivi d'un '(' puis de ses arguments (y compris le deuxième, qu'on veut), puis d'un ')', on est sur qu'il ne peut pas y avoir deux CB_ dans un même record et que le record suivant un record qui contient CB_ contient son deuxième arguments (en supposant qu'il n'y ait pas de parenthèses dans les arguments de CB_...) et pas de CB_.
NR et FNR, ça compte le numéro du record. Pour avoir le numéro de la ligne, if faut compter le nombre de CR. Pour ça, on utilise gsub (qui renvoie le nombre de substitutions faites). c'est "n" qui contient le numéro de la ligne (on l'initialise à 1 pour chaque nouveau fichier (quand FNR == 1)).
Ok, c'est plus clair.
Mais la manip avec saved_line / getline ?
RS=[()], ben c'est '(' ou ')'. Comme ça, vu qu'un CB_ est toujours suivi d'un '(' puis de ses arguments (y compris le deuxième, qu'on veut), puis d'un ')', on est sur qu'il ne peut pas y avoir deux CB_ dans un même record et que le record suivant un record qui contient CB_ contient son deuxième arguments (en supposant qu'il n'y ait pas de parenthèses dans les arguments de CB_...) et pas de CB_.
Heu, va falloir que je me replonge dans mon manuel gawk. Le record c'est CB_qqchose (retourné par la regexp /<CB_w*/) ou ce qui est contenu entre les () ? Ou les 2 selon le cas ? Je crois que je me méprend entre field et record...
Sébastien Kirche
On 6 Feb 2004, Stephane Chazelas wrote:
[...]
Qu'on va réécrire:
Merci pour cet effort, j'aime bien les variableParlantes et les
variables_en_clair :)
NR et FNR, ça compte le numéro du record. Pour avoir le numéro
de la ligne, if faut compter le nombre de CR. Pour ça, on
utilise gsub (qui renvoie le nombre de substitutions faites).
c'est "n" qui contient le numéro de la ligne (on l'initialise à
1 pour chaque nouveau fichier (quand FNR == 1)).
Ok, c'est plus clair.
Mais la manip avec saved_line / getline ?
RS=[()], ben c'est '(' ou ')'. Comme ça, vu qu'un CB_ est
toujours suivi d'un '(' puis de ses arguments (y compris le
deuxième, qu'on veut), puis d'un ')', on est sur qu'il ne peut
pas y avoir deux CB_ dans un même record et que le record
suivant un record qui contient CB_ contient son deuxième
arguments (en supposant qu'il n'y ait pas de parenthèses dans
les arguments de CB_...) et pas de CB_.
Heu, va falloir que je me replonge dans mon manuel gawk. Le record c'est
CB_qqchose (retourné par la regexp /<CB_w*/) ou ce qui est contenu entre
les () ? Ou les 2 selon le cas ?
Je crois que je me méprend entre field et record...
NR et FNR, ça compte le numéro du record. Pour avoir le numéro de la ligne, if faut compter le nombre de CR. Pour ça, on utilise gsub (qui renvoie le nombre de substitutions faites). c'est "n" qui contient le numéro de la ligne (on l'initialise à 1 pour chaque nouveau fichier (quand FNR == 1)).
Ok, c'est plus clair.
Mais la manip avec saved_line / getline ?
RS=[()], ben c'est '(' ou ')'. Comme ça, vu qu'un CB_ est toujours suivi d'un '(' puis de ses arguments (y compris le deuxième, qu'on veut), puis d'un ')', on est sur qu'il ne peut pas y avoir deux CB_ dans un même record et que le record suivant un record qui contient CB_ contient son deuxième arguments (en supposant qu'il n'y ait pas de parenthèses dans les arguments de CB_...) et pas de CB_.
Heu, va falloir que je me replonge dans mon manuel gawk. Le record c'est CB_qqchose (retourné par la regexp /<CB_w*/) ou ce qui est contenu entre les () ? Ou les 2 selon le cas ? Je crois que je me méprend entre field et record...
Sébastien Kirche
Stephane Chazelas
2004-02-06, 17:43(+01), Sébastien Kirche: [...]
saved_line=$0 getline [...]
$0 = saved_line $0 } n += gsub("r", "", $0) [...]
Ok, c'est plus clair.
Mais la manip avec saved_line / getline ?
getline, ça va chercher la ligne (enfin le record) suivante, et on a pas encore compté les CR de du record courant (pour mettre à jour "n"), donc on la stocke pour que le gsub de la fin compte dans les deux lignes à la fois.
[...]
Heu, va falloir que je me replonge dans mon manuel gawk. Le record c'est CB_qqchose (retourné par la regexp /<CB_w*/) ou ce qui est contenu entre les () ? Ou les 2 selon le cas ? Je crois que je me méprend entre field et record... [...]
Le record, c'est ce que sépare RS (record separator), c'est la base de travail de awk. Par défaut, c'est les lignes du fichiers.
Toutes les <condition> <action> s'opère tour à tour sur les records.
getline, ça va chercher la ligne (enfin le record) suivante, et
on a pas encore compté les CR de du record courant (pour mettre
à jour "n"), donc on la stocke pour que le gsub de la fin compte
dans les deux lignes à la fois.
[...]
Heu, va falloir que je me replonge dans mon manuel gawk. Le record c'est
CB_qqchose (retourné par la regexp /<CB_w*/) ou ce qui est contenu entre
les () ? Ou les 2 selon le cas ?
Je crois que je me méprend entre field et record...
[...]
Le record, c'est ce que sépare RS (record separator), c'est la
base de travail de awk. Par défaut, c'est les lignes du
fichiers.
Toutes les <condition> <action> s'opère tour à tour sur les
records.
getline, ça va chercher la ligne (enfin le record) suivante, et on a pas encore compté les CR de du record courant (pour mettre à jour "n"), donc on la stocke pour que le gsub de la fin compte dans les deux lignes à la fois.
[...]
Heu, va falloir que je me replonge dans mon manuel gawk. Le record c'est CB_qqchose (retourné par la regexp /<CB_w*/) ou ce qui est contenu entre les () ? Ou les 2 selon le cas ? Je crois que je me méprend entre field et record... [...]
Le record, c'est ce que sépare RS (record separator), c'est la base de travail de awk. Par défaut, c'est les lignes du fichiers.
Toutes les <condition> <action> s'opère tour à tour sur les records.
getline, ça va chercher la ligne (enfin le record) suivante, et on a pas encore compté les CR de du record courant (pour mettre à jour "n"), donc on la stocke pour que le gsub de la fin compte dans les deux lignes à la fois.
Ah ok : optimisation.
[...]
Heu, va falloir que je me replonge dans mon manuel gawk. Le record c'est CB_qqchose (retourné par la regexp /<CB_w*/) ou ce qui est contenu entre les () ? Ou les 2 selon le cas ? Je crois que je me méprend entre field et record... [...]
Le record, c'est ce que sépare RS (record separator), c'est la base de travail de awk. Par défaut, c'est les lignes du fichiers.
Toutes les <condition> <action> s'opère tour à tour sur les records.
[...]
Donc (histoire de voir si j'ai bien tout compris) : - (mettons qu'on soit sur une fonction CB_xxx) lorsqu'on en est au "if (match...)", le record (<=> $0) contient tout le fichier depuis le début /ou depuis la dernière parenthèse fermante - le premier substr récupère le nom CB_xxx - on compte les cr précédents - le getline nous fait alors que record (<=> $0) contient tous les paramètres de notre CB_xxx avec $1=param1, $2=param2, etc - on présente nos données formatées et on compte les cr - lorsqu'on arrive sur la prochaine itération, le record contient tout depuis la parenthèse fermante de la CB_xxx jusqu'à la prochaine parenthèses ouvrante ou la fin du fichier
C'est bien ça ? Ouf !
Merci pour les explications détaillées.
Sébastien Kirche
On va y arriver :)
On 6 fév 2004, Stephane Chazelas wrote:
[...]
Mais la manip avec saved_line / getline ?
getline, ça va chercher la ligne (enfin le record) suivante, et
on a pas encore compté les CR de du record courant (pour mettre
à jour "n"), donc on la stocke pour que le gsub de la fin compte
dans les deux lignes à la fois.
Ah ok : optimisation.
[...]
Heu, va falloir que je me replonge dans mon manuel gawk. Le record c'est
CB_qqchose (retourné par la regexp /<CB_w*/) ou ce qui est contenu
entre les () ? Ou les 2 selon le cas ? Je crois que je me méprend entre
field et record...
[...]
Le record, c'est ce que sépare RS (record separator), c'est la
base de travail de awk. Par défaut, c'est les lignes du
fichiers.
Toutes les <condition> <action> s'opère tour à tour sur les
records.
[...]
Donc (histoire de voir si j'ai bien tout compris) :
- (mettons qu'on soit sur une fonction CB_xxx) lorsqu'on en est au "if
(match...)", le record (<=> $0) contient tout le fichier depuis le début /ou
depuis la dernière parenthèse fermante
- le premier substr récupère le nom CB_xxx
- on compte les cr précédents
- le getline nous fait alors que record (<=> $0) contient tous les
paramètres de notre CB_xxx avec $1=param1, $2=param2, etc
- on présente nos données formatées et on compte les cr
- lorsqu'on arrive sur la prochaine itération, le record contient tout
depuis la parenthèse fermante de la CB_xxx jusqu'à la prochaine
parenthèses ouvrante ou la fin du fichier
getline, ça va chercher la ligne (enfin le record) suivante, et on a pas encore compté les CR de du record courant (pour mettre à jour "n"), donc on la stocke pour que le gsub de la fin compte dans les deux lignes à la fois.
Ah ok : optimisation.
[...]
Heu, va falloir que je me replonge dans mon manuel gawk. Le record c'est CB_qqchose (retourné par la regexp /<CB_w*/) ou ce qui est contenu entre les () ? Ou les 2 selon le cas ? Je crois que je me méprend entre field et record... [...]
Le record, c'est ce que sépare RS (record separator), c'est la base de travail de awk. Par défaut, c'est les lignes du fichiers.
Toutes les <condition> <action> s'opère tour à tour sur les records.
[...]
Donc (histoire de voir si j'ai bien tout compris) : - (mettons qu'on soit sur une fonction CB_xxx) lorsqu'on en est au "if (match...)", le record (<=> $0) contient tout le fichier depuis le début /ou depuis la dernière parenthèse fermante - le premier substr récupère le nom CB_xxx - on compte les cr précédents - le getline nous fait alors que record (<=> $0) contient tous les paramètres de notre CB_xxx avec $1=param1, $2=param2, etc - on présente nos données formatées et on compte les cr - lorsqu'on arrive sur la prochaine itération, le record contient tout depuis la parenthèse fermante de la CB_xxx jusqu'à la prochaine parenthèses ouvrante ou la fin du fichier
C'est bien ça ? Ouf !
Merci pour les explications détaillées.
Sébastien Kirche
Stephane Chazelas
2004-02-06, 22:21(+01), Sébastien Kirche: [...]
getline, ça va chercher la ligne (enfin le record) suivante, et on a pas encore compté les CR de du record courant (pour mettre à jour "n"), donc on la stocke pour que le gsub de la fin compte dans les deux lignes à la fois.
Ah ok : optimisation.
Comment ça ?
[...]
Donc (histoire de voir si j'ai bien tout compris) : - (mettons qu'on soit sur une fonction CB_xxx) lorsqu'on en est au "if (match...)", le record (<=> $0) contient tout le fichier depuis le début /ou depuis la dernière parenthèse fermante
ou ouvrante. Comme dans f(3, CB_blah(...
- le premier substr récupère le nom CB_xxx - on compte les cr précédents - le getline nous fait alors que record (<=> $0) contient tous les paramètres de notre CB_xxx avec $1=param1, $2=param2, etc - on présente nos données formatées et on compte les cr - lorsqu'on arrive sur la prochaine itération, le record contient tout depuis la parenthèse fermante de la CB_xxx jusqu'à la prochaine parenthèses ouvrante ou la fin du fichier
getline, ça va chercher la ligne (enfin le record) suivante, et
on a pas encore compté les CR de du record courant (pour mettre
à jour "n"), donc on la stocke pour que le gsub de la fin compte
dans les deux lignes à la fois.
Ah ok : optimisation.
Comment ça ?
[...]
Donc (histoire de voir si j'ai bien tout compris) :
- (mettons qu'on soit sur une fonction CB_xxx) lorsqu'on en est au "if
(match...)", le record (<=> $0) contient tout le fichier depuis le début /ou
depuis la dernière parenthèse fermante
ou ouvrante. Comme dans f(3, CB_blah(...
- le premier substr récupère le nom CB_xxx
- on compte les cr précédents
- le getline nous fait alors que record (<=> $0) contient tous les
paramètres de notre CB_xxx avec $1=param1, $2=param2, etc
- on présente nos données formatées et on compte les cr
- lorsqu'on arrive sur la prochaine itération, le record contient tout
depuis la parenthèse fermante de la CB_xxx jusqu'à la prochaine
parenthèses ouvrante ou la fin du fichier
getline, ça va chercher la ligne (enfin le record) suivante, et on a pas encore compté les CR de du record courant (pour mettre à jour "n"), donc on la stocke pour que le gsub de la fin compte dans les deux lignes à la fois.
Ah ok : optimisation.
Comment ça ?
[...]
Donc (histoire de voir si j'ai bien tout compris) : - (mettons qu'on soit sur une fonction CB_xxx) lorsqu'on en est au "if (match...)", le record (<=> $0) contient tout le fichier depuis le début /ou depuis la dernière parenthèse fermante
ou ouvrante. Comme dans f(3, CB_blah(...
- le premier substr récupère le nom CB_xxx - on compte les cr précédents - le getline nous fait alors que record (<=> $0) contient tous les paramètres de notre CB_xxx avec $1=param1, $2=param2, etc - on présente nos données formatées et on compte les cr - lorsqu'on arrive sur la prochaine itération, le record contient tout depuis la parenthèse fermante de la CB_xxx jusqu'à la prochaine parenthèses ouvrante ou la fin du fichier
getline, ça va chercher la ligne (enfin le record) suivante, et on a pas encore compté les CR de du record courant (pour mettre à jour "n"), donc on la stocke pour que le gsub de la fin compte dans les deux lignes à la fois.
Ah ok : optimisation.
Comment ça ?
Cela peut être écrit différemment ? J'avais compris le fait de compter les 2 lignes en même temps comme une façon optimisée de compter de la part d'un utilisateur awk averti... Mais bref, je vois bien comment fonctionne, c'est l'essentiel.
[...]
Donc (histoire de voir si j'ai bien tout compris) : - (mettons qu'on soit sur une fonction CB_xxx) lorsqu'on en est au "if (match...)", le record (<=> $0) contient tout le fichier depuis le début /ou depuis la dernière parenthèse fermante
ou ouvrante. Comme dans f(3, CB_blah(...
Euh oui, en effet.
[...]
C'est bien ça ? Ouf !
Oui, ça semble correct.
Bien :)
Encore merci pour avoir pris la peine de bien m'expliquer tout cela.
Sébastien Kirche.
On 7 fév 2004, Stephane Chazelas wrote:
2004-02-06, 22:21(+01), Sébastien Kirche:
[...]
getline, ça va chercher la ligne (enfin le record) suivante, et
on a pas encore compté les CR de du record courant (pour mettre
à jour "n"), donc on la stocke pour que le gsub de la fin compte
dans les deux lignes à la fois.
Ah ok : optimisation.
Comment ça ?
Cela peut être écrit différemment ?
J'avais compris le fait de compter les 2 lignes en même temps comme une
façon optimisée de compter de la part d'un utilisateur awk averti...
Mais bref, je vois bien comment fonctionne, c'est l'essentiel.
[...]
Donc (histoire de voir si j'ai bien tout compris) :
- (mettons qu'on soit sur une fonction CB_xxx) lorsqu'on en est au "if
(match...)", le record (<=> $0) contient tout le fichier depuis le début /ou
depuis la dernière parenthèse fermante
ou ouvrante. Comme dans f(3, CB_blah(...
Euh oui, en effet.
[...]
C'est bien ça ? Ouf !
Oui, ça semble correct.
Bien :)
Encore merci pour avoir pris la peine de bien m'expliquer tout cela.
getline, ça va chercher la ligne (enfin le record) suivante, et on a pas encore compté les CR de du record courant (pour mettre à jour "n"), donc on la stocke pour que le gsub de la fin compte dans les deux lignes à la fois.
Ah ok : optimisation.
Comment ça ?
Cela peut être écrit différemment ? J'avais compris le fait de compter les 2 lignes en même temps comme une façon optimisée de compter de la part d'un utilisateur awk averti... Mais bref, je vois bien comment fonctionne, c'est l'essentiel.
[...]
Donc (histoire de voir si j'ai bien tout compris) : - (mettons qu'on soit sur une fonction CB_xxx) lorsqu'on en est au "if (match...)", le record (<=> $0) contient tout le fichier depuis le début /ou depuis la dernière parenthèse fermante
ou ouvrante. Comme dans f(3, CB_blah(...
Euh oui, en effet.
[...]
C'est bien ça ? Ouf !
Oui, ça semble correct.
Bien :)
Encore merci pour avoir pris la peine de bien m'expliquer tout cela.