grep expressão regular para evitar correspondência de ponto-e-vírgula no final

1

Eu gostaria de encontrar todas as declarações de funções que terminam com "_DB" em um arquivo e evitar perl e pipes.

Por exemplo:

prep_DB();

init_DB(DB *database, char *params[])
{
  open_DB(database);
}

prep_DB() {
  open_DB(database); // open
}

FILE * load_DB(const char * exppath, const char * expfname)
{}

deve corresponder apenas à segunda linha e à penúltima linha. A linha prep_DB() { pode estar presente ou ausente.

Atualmente, o comando a seguir encontra todas as invocações de função:

grep -E '.*_DB(.*)' file

No entanto, estou tendo problemas em negar o ponto-e-vírgula no final. O tópico mais próximo que veio para explicar como funciona é isso ; no entanto, parece que o ponto-e-vírgula é um caractere especial, porque o conselho não está funcionando. Como posso contornar essa limitação?

    
por Alex 23.08.2017 / 21:48

2 respostas

1

Assumindo que este é um arquivo de origem C chamado file.c .

Usando ctags :

$ ctags file.c

Isso cria um arquivo chamado tags :

$ cat tags
init_DB file.c  /^init_DB(DB *database, char *params[])$/
load_DB file.c  /^FILE * load_DB(const char * exppath, const char * /
prep_DB file.c  /^prep_DB() {$/

Isso pode ser usado com vi ou vim para pular automaticamente para as definições de função.

Você também pode analisar esse arquivo com cut e grep :

$ cut -f 1 tags | grep '_DB$'
init_DB
load_DB
prep_DB

Nos sistemas Ubuntu, a instalação de ctags instalará exuberant-ctags , o que fornece uma saída tags mais detalhada:

$ cat tags
!_TAG_FILE_FORMAT       2       /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED       1       /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR    Darren Hiebert  /[email protected]/
!_TAG_PROGRAM_NAME      Exuberant Ctags //
!_TAG_PROGRAM_URL       http://ctags.sourceforge.net    /official site/
!_TAG_PROGRAM_VERSION   5.9~svn20110310 //
init_DB file.c  /^init_DB(DB *database, char *params[])$/;"     f
load_DB file.c  /^FILE * load_DB(const char * exppath, const char * expfname)$/;"       f
prep_DB file.c  /^prep_DB() {$/;"       f

Aqui podemos ter certeza de obter apenas definições de função com

$ awk '$NF == "f" && $1 ~ /_DB$/ { print $1 }' tags
init_DB
load_DB
prep_DB

O ponto aqui é que é melhor usar um interpretador de linguagem C dedicado do que tentar considerar todos os estilos de programação possíveis em um script awk ou uma expressão regular com grep que analisa o código C.

Você também pode fazer

$ ctags -x file.c
init_DB          function      3 file.c           init_DB(DB *database, char *params[])
load_DB          function     12 file.c           FILE * load_DB(const char * exppath, const char * expfname)
prep_DB          function      8 file.c           prep_DB() {

e depois analisar / filtrar isso de qualquer maneira que você precisar. O número é o número da linha da definição. Tudo se resume ao que você entende por "querer encontrar".

    
por 23.08.2017 / 22:52
0

Eu decidi publicar o resumo da discussão sobre o 20 + -comentário acima.

Uma solução foi fornecida por @don_crissti, que sugeriu o comando:

$ grep -E '.*_DB([^;]*)$' <filename>

que produz a saída

init_DB(DB *database, char *params[])
prep_DB() {
FILE * load_DB(const char * exppath, const char * expfname)

Com base em sua sugestão, criei o seguinte comando para excluir o resultado do meio, se necessário:

$ grep -E '_DB\(.*\)$' <filename>
    
por 23.08.2017 / 22:29