grep: exibe o nome do arquivo uma vez e, em seguida, exibe o contexto com números de linha

15

Nosso código-fonte tem códigos de erro espalhados por toda parte. Encontrá-los é fácil com o grep, mas eu gostaria de uma função bash find_code que eu possa executar (por exemplo, find_code #### ) que fornecerá a saída ao longo destas linhas:

/home/user/path/to/source.c

85     imagine this is code
86     this is more code
87     {
88         nicely indented
89         errorCode = 1111
90         that's the line that matched!
91         ok this block is ending
92     }
93 }

Aqui está o que tenho atualmente:

find_code()
{
    # "= " included to avoid matching unrelated number series
    # SRCDIR is environment variable, parent dir of all of projects
    FILENAME= grep -r "= ${1}" ${SRCDIR}
    echo ${FILENAME}
    grep -A5 -B5 -r "= ${1}" ${SRCDIR} | sed -e 's/.*\.c\[-:]//g'
}

Problemas:

1) Isso não fornece números de linha

2) corresponde apenas aos arquivos de origem .c. Estou tendo problemas para obter sed para corresponder a .c, .cs, .cpp e outros arquivos de origem. Nós usamos C, então simplesmente combinar - ou: (os caracteres que o grep anexa ao nome do arquivo antes de cada linha de código) corresponde a object->pointers e bagunça tudo.

    
por TravisThomas 09.08.2013 / 22:15

2 respostas

11

Eu mudaria algumas coisas sobre.

find_code() { 
    # assign all arguments (not just the first ${1}) to MATCH
    # so find_code can be used with multiple arguments:
    #    find_code errorCode
    #    find_code = 1111
    #    find_code errorCode = 1111
    MATCH="$@" 

    # For each file that has a match in it (note I use '-l' to get just the file name
    # that matches, and not the display of the matching part) I.e we get an output of:
    #
    #       srcdir/matching_file.c
    # NOT:
    #       srcdir/matching_file.c:       errorCode = 1111
    #
    grep -lr "$MATCH" ${SRCDIR} | while read file 
    do 
        # echo the filename
        echo ${file}
        # and grep the match in that file (this time using '-h' to suppress the 
        # display of the filename that actually matched, and '-n' to display the 
        # line numbers)
        grep -nh -A5 -B5 "$MATCH" "${file}"
    done 
}
    
por 09.08.2013 / 22:51
3

Você pode usar find com dois -exec s, o segundo será executado somente se o primeiro for bem-sucedido, por exemplo, pesquisando apenas nos arquivos .cpp , .c e .cs :

find_code() {
find ${SRCDIR} -type f \
\( -name \*.cpp -o -name \*.c -o -name \*.cs \) \
-exec grep -l "= ${1}" {} \; -exec grep -n -C5 "= ${1}" {} \;
}

para que o primeiro grep imprima os nomes de arquivo que contêm seu padrão e o segundo imprima as linhas correspondentes + contexto, numerados, dos respectivos arquivos.

    
por 18.08.2015 / 15:19