grep: 파일 이름을 한 번 표시한 다음 줄 번호로 컨텍스트를 표시합니다.

grep: 파일 이름을 한 번 표시한 다음 줄 번호로 컨텍스트를 표시합니다.

우리의 소스 코드는 버그가 있는 코드로 가득 차 있습니다. 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 }

이것이 내가 현재 가지고 있는 것입니다:

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 및 기타 소스 파일과 일치하도록 sed를 얻을 수 없습니다. 하지만 우리는 C를 사용하므로 단순히 - 또는 :(각 코드 줄 앞에 파일 이름에 grep을 추가함)을 일치시키면 object->pointers모든 것이 일치하고 엉망이 됩니다.

답변1

나는 몇 가지를 바꿀 것입니다.

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 
}

답변2

find두 개의 s를 사용 -exec하고 첫 번째가 성공한 경우에만 두 번째를 실행할 수 있습니다. 예를 들어 .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패턴이 포함된 파일 이름을 인쇄하고 두 번째는 해당 파일에서 일치하는 줄 + 컨텍스트(번호)를 인쇄합니다.

답변3

또 다른 옵션: Git:

git grep --heading xxxxxxxxx

또한 존경합니다 .gitignore.

git repo 외부에 추가되었습니다 --no-index.

답변4

다음은 특정 플래그를 구문 분석할 필요가 없는 유사하지만 더 강력한 접근 방식입니다.

find_code {
    reset="\e[0m"
    purple="\e[35m"

    mapfile -t files < <(grep -l -R "$@" --color=none)
    for fn in "${files[@]}"; do 
        printf "$purple%s$reset\n\n" "$fn"; 
        grep "$@" "$fn"
        printf "\n"
    done
}

그러나 완성도를 위해,립그렙기본 출력은 원하는 형식입니다.

관련 정보