Nic*_*rto 2 regex awk text-extraction header-files
我正在尝试制作一个"脚本" - 本质上是一个awk命令 - 在.c文件中提取C代码函数的原型,以自动生成一个头.h.我是awk的新手,所以我没有得到所有细节.
这是源.c的示例:
dict_t dictup(dict_t d, const char * key, const char * newval)
{
int i = dictlook(d, key);
if (i == DICT_NOT_FOUND) {
fprintf(stderr, "key \"%s\" doesn't exist.\n", key);
dictdump(d);
}
else {
strncpy(d.entry[i].val, newval, DICTENT_VALLENGTH);
}
return d;
}
dict_t* dictrm(dict_t* d, const char * key) {
int i = dictlook(d, key);
if (i == DICT_NOT_FOUND) {
fprintf(stderr, "key \"%s\" doesn't exist.\n", key);
dictdump(d);
}
else {
d->entry[i] = d->entry[--d.size];
}
if ( ((float)d->size)/d.maxsise < 0.25 ) {
d->maxsize /= 2;
d->entry = realloc(d->entry, d->maxsize*sizeof(dictent_t*));
}
return d;
}
Run Code Online (Sandbox Code Playgroud)
而我想要产生的东西:
dict_t dictup(dict_t d, const char * key, const char *newval);
dict_t* dictrm(dict_t* d, const char * key);
Run Code Online (Sandbox Code Playgroud)
我对完整正则表达式的命令如下所示:
awk '/^[a-zA-Z*_]+[:space:]+[a-zA-Z*_]+[:space:]*\(.*?\)/{ print $0 }' dict3.c
Run Code Online (Sandbox Code Playgroud)
但我对它一无所知.所以我试图挤压它只是为了看看我能不能带来一些东西.我试过这个:
awk '/^[a-zA-Z*_]+[:space:]+[a-zA-Z*_]+/{ print $0 }' dict3.c
Run Code Online (Sandbox Code Playgroud)
我明白了:
dictent_t* dictentcreate(const char * key, const char * val)
dict_t* dictcreate()
dict_t* dictadd(dict_t* d, const char * key, const char * val)
dict_t dictup(dict_t d, const char * key, const char * newval)
dict_t* dictrm(dict_t* d, const char * key) {
Run Code Online (Sandbox Code Playgroud)
这是许多奇迹的来源!
;在每个正则表达式的末尾添加?注意:自从我写这个答案以来,这个问题发生了很大变化.
替换[:space:]为[[:space:]]:
$ awk '/^[a-zA-Z*_]+[[:space:]]+[a-zA-Z*_]+[[:space:]]*[(].*?[)]/{ print $0 }' dict3.c
dictent_t* dictentcreate(const char * key, const char * val)
dict_t* dictcreate()
void dictdestroy(*dict_t d)
void dictdump(dict_t *d)
int dictlook(dict_t *d, const char * key)
int dictget(char* s, dict_t *d, const char *key)
dict_t* dictadd(dict_t* d, const char * key, const char * val)
dict_t dictup(dict_t d, const char * key, const char *newval)
dict_t* dictrm(dict_t* d, const char * key)
Run Code Online (Sandbox Code Playgroud)
其原因是,[:space:]将匹配任何字符:,s,p,a,c,或e.这不是你想要的.
你想要[[:space:]]哪个匹配任何空格.
本机Sun/Solaris awk是众所周知的错误填充.如果您在该平台上,请尝试nawk或/usr/xpg4/bin/awk 或/usr/xpg6/bin/awk.
可以使用非常类似的方法sed.这使用基于你的正则表达式:
$ sed -n '/^[a-zA-Z_*]\+[ \t]\+[a-zA-Z*]\+ *[(]/p' dict3.c
dictent_t* dictentcreate(const char * key, const char * val)
dict_t* dictcreate()
void dictdestroy(*dict_t d)
void dictdump(dict_t *d)
int dictlook(dict_t *d, const char * key)
int dictget(char* s, dict_t *d, const char *key)
dict_t* dictadd(dict_t* d, const char * key, const char * val)
dict_t dictup(dict_t d, const char * key, const char *newval)
dict_t* dictrm(dict_t* d, const char * key)
Run Code Online (Sandbox Code Playgroud)
-n除非我们明确要求,否则该选项告诉sed不要打印./.../p如果斜杠内的正则表达式匹配,则构造告诉sed打印该行.
Ed Morton建议的正则表达式的所有改进也适用于此.
以上也可以用于perl:
perl -ne 'print if /^[a-zA-Z_*]+[ \t]+[a-zA-Z*]+ *[(]/' dict3.c
Run Code Online (Sandbox Code Playgroud)