Awk与我的所有参赛作品都不匹配

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)

这是许多奇迹的来源!

  • 为什么第一个正则表达式不起作用?
  • 为什么第二个已经获得了一些声明,但不是全部?我保证在宣布之前没有空格.我想由于缩进,它没有捕获代码的其他部分,如变量声明.
  • 第三个问题,为什么它抓住我需要表达的所有行?
  • 最后一个,我怎样才能;在每个正则表达式的末尾添加?

Joh*_*024 5

注意:自从我写这个答案以来,这个问题发生了很大变化.

替换[: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:]]哪个匹配任何空格.

太阳/ Solaris上

本机Sun/Solaris awk是众所周知的错误填充.如果您在该平台上,请尝试nawk/usr/xpg4/bin/awk/usr/xpg6/bin/awk.

使用sed

可以使用非常类似的方法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:

perl -ne  'print if /^[a-zA-Z_*]+[ \t]+[a-zA-Z*]+ *[(]/' dict3.c
Run Code Online (Sandbox Code Playgroud)