grep:显示文件名一次,然后显示带有行号的上下文

Tra*_*mas 16 grep sed awk regular-expression

我们的源代码中散布着错误代码。使用 grep 很容易找到它们,但我想要一个find_code我可以执行的 bash 函数(例如find_code ####),它将提供以下几行的输出:

/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 }
Run Code Online (Sandbox Code Playgroud)

这是我目前所拥有的:

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'
}
Run Code Online (Sandbox Code Playgroud)

问题:

1)这不提供行号

2) 它只匹配 .c 源文件。我在使用 sed 匹配 .c、.cs、.cpp 和其他源文件时遇到问题。但是,我们确实使用 C,因此只需匹配 - 或 :(grep 在每行代码之前附加到文件名的字符)匹配object->pointers并弄乱所有内容。

Dra*_*oan 11

我会改变一些事情。

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 
}
Run Code Online (Sandbox Code Playgroud)