grep: hiển thị tên tệp một lần, sau đó hiển thị ngữ cảnh với số dòng


16

Mã nguồn của chúng tôi có mã lỗi nằm rải rác trong suốt. Tìm kiếm chúng thật dễ dàng với grep, nhưng tôi muốn một hàm bash find_codemà tôi có thể thực thi (ví dụ find_code ####:) sẽ cung cấp đầu ra dọc theo các dòng này:

/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 }

Đây là những gì tôi có hiện tại:

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'
}

Các vấn đề:

1) Điều này không cung cấp số dòng

2) nó chỉ phù hợp với các tập tin nguồn .c. Tôi gặp sự cố khi nhận sed để khớp với các tệp .c, .cs, .cpp và các tệp nguồn khác. Mặc dù vậy, chúng tôi sử dụng C, do đó, chỉ cần khớp - hoặc: (các ký tự grep gắn vào tên tệp trước mỗi dòng mã) khớp object->pointersvà làm rối tung mọi thứ.

Câu trả lời:


11

Tôi sẽ thay đổi một vài điều về.

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 
}

Tôi đã điều chỉnh lại thông số kỹ thuật của mình - tôi chỉ đơn giản muốn tìm mã lỗi. Vì vậy MATCH="= ${1}". Tôi cũng đã thêm --include=*.c --include=*.cpp --include=*.java --include=*.csđể giới hạn tìm kiếm vào các tập tin nguồn. Cảm ơn!
TravisThomas

1
Tốt, rất vui vì bạn đã xoay sở để điều chỉnh tốt nhu cầu của mình :)
Drav Sloan

3

Bạn có thể sử dụng findvới hai -execs, điều thứ hai sẽ được thực hiện chỉ khi là người đầu tiên thành công, ví dụ như tìm kiếm chỉ trong .cpp, .c.cstập tin:

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

vì vậy, cái đầu tiên grepin tên tệp chứa mẫu của bạn và cái thứ hai sẽ in các dòng trùng khớp + bối cảnh, được đánh số, từ các tệp tương ứng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.