grep: แสดงชื่อไฟล์หนึ่งครั้งจากนั้นแสดงบริบทด้วยหมายเลขบรรทัด


16

ซอร์สโค้ดของเรามีรหัสข้อผิดพลาดกระจายอยู่ทั่วไป การค้นหามันเป็นเรื่องง่ายด้วย grep แต่ฉันต้องการฟังก์ชั่นทุบตีfind_codeที่ฉันสามารถดำเนินการ (เช่น. 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 }

นี่คือสิ่งที่ฉันมีในปัจจุบัน:

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

ปัญหา:

1) สิ่งนี้ไม่ได้ระบุหมายเลขบรรทัด

2) ตรงกับไฟล์ต้นฉบับ. c เท่านั้น ฉันมีปัญหาในการติดตั้ง. c, .cs, .cpp และไฟล์ต้นฉบับอื่น ๆ อย่างไรก็ตามเราใช้ C ดังนั้นเพียงจับคู่ - หรือ: (อักขระที่ grep ต่อท้ายชื่อไฟล์ก่อนโค้ดแต่ละบรรทัด) จะจับคู่object->pointersและทำให้ทุกอย่างยุ่ง

คำตอบ:


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 
}

ฉันปรับกลับไปเป็นข้อมูลจำเพาะของฉัน - ฉันแค่ต้องการค้นหารหัสข้อผิดพลาด MATCH="= ${1}"ดังนั้น ฉันยังเพิ่ม--include=*.c --include=*.cpp --include=*.java --include=*.csเพื่อ จำกัด การค้นหาไฟล์ต้นฉบับ ขอบคุณ!
TravisThomas

1
ดีโอ้ดีใจที่คุณมีการจัดการที่จะได้รับมันปรับแต่งเพื่อความต้องการของคุณ :)
Drav โลน

3

คุณสามารถใช้findกับสอง-execs, คนที่สองจะดำเนินการเฉพาะในกรณีที่คนแรกเป็นที่ประสบความสำเร็จเช่นการค้นหาเฉพาะใน.cpp, .cและ.csไฟล์:

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

ดังนั้นก่อนgrepพิมพ์ชื่อไฟล์ที่มีรูปแบบของคุณและคนที่สองจะพิมพ์บรรทัดที่ตรงกัน + บริบทหมายเลขจากไฟล์ที่เกี่ยวข้อง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.