재귀 grep : 특정 디렉토리 제외


49

재귀 grep을 많이 사용하여 특정 내용의 소스 파일을 찾습니다.

grep -Rni "myfunc" .

큰 코드베이스에서는 이것이 느려질 수 있으므로 --incldue를 사용하여 확장을 제한 / 허용합니다.

grep -Rni --include=*.java "myfunc" .

그러나 전체 하위 디렉토리를 제외 (제거)하는 것이 더 효율적이라고 생각합니다.

grep -Rni --exclude=/.svn/ "myfunc" .

그러나 --exclude는 * .java와 같은 파일 패턴 만 지원합니다. 디렉토리를 제외하려면 어떻게해야합니까?

답변:


10

당신은 ack를 볼 수 있습니다 .

방금 사용하기 시작했지만 이것에 적합합니다.


ack는 꽤 좋아 보인다. 원하지 않는 파일을 직관적으로 제외시키는 것이 좋습니다. --nogroup 옵션은 -Rni grep으로하는 유사한 출력 제공
가보

2
Ack는 약간 느립니다. Silver Searcher (Ag) 또는 ripgrep (rg)를 사용해보십시오.
user31389

62
grep -r --exclude-dir=dev --exclude-dir=sys --exclude-dir=proc PATTERN data

출처 : https://stackoverflow.com/questions/2799246/grep-clude-a-specific-folder-using


17
이것은 재귀 적으로 제외됩니다. ./devALONG WITH에서 제외됩니다 ./foo/bar/dev. --exclude-dir=./dev첫 번째 경우에만 적용 하십시오 .
Cory Walker

4
globbing 하여이 bash grep -r --exclude-dir={dev,sys,proc} PATTERN data 문제를 약간 줄일 수도 있습니다. globbing 의 유일한 문제는 내 bash에서 작동시키지 못한다는 것입니다. 이 경우 나는 그것들을 분리해야합니다.
b01

3
또한 {}는 둘 이상의 항목을 넣은 경우에만 작동합니다. 즉 --exclude-dir = {home, .svn}은 작동하지만 --exclude-dir = {. svn}은 작동하지 않습니다. 처음에 1 개의 항목으로 테스트하기 때문에 {}이 (가) 작동하지 않는 이유를 알아내는 데 시간이 낭비되었습니다.
林果 皞

{}단일 항목과 함께 사용 하는 경우 아마도 배열을 만들기 위해 단항 쉼표가 필요할 것입니다 (Bash가 어떻게 처리하는지 확실하지 않음). 대신 .bash_aliases에서 일반적으로 항상 제외하려는 폴더 목록을 반복하는 별칭을 만듭니다. 예를 들어 .git, .svn, .hg, .cache와 함께 루프를 통해 추가합니다. --exclude-dir $dir그런 다음 해당 배열을 grep 별명으로 확장하십시오.
dragon788

6

대신 find를 사용할 수 있습니다.

find . -not -path "*/.svn*" -not -type d -exec grep -ni "myfunc" {} \; -print

좋아, 그래서 조금 뒤로, grep 결과를 먼저 얻은 다음 경로 를 얻습니다 . 어쩌면 다른 누군가가 더 나은 대답을 가지고 있습니까?


3
좋아, 난 그게 많이 좋아. 물론 더 유연하게 찾을 수 있습니다. 출력 간의 유일한 차이점은 "grep -Rni"는 각 일치에 대한 파일 이름을 인쇄하는 반면 "find -exec grep"은 파일 이름을 한 줄에 인쇄 한 다음 각 일치에 대해 한 줄을 인쇄합니다 (행 번호 및 행 내용 포함) ). "그렙 -Hni"힘을 파일 이름을 사용하여 각 행에 표시되는
가보

grep --exclude-dir을 사용하지 않고 이처럼 거친 시스템에서 작동하는 유일한 답변을 제공해 주셔서 감사합니다.
Dmitri DB

2

여기 내 프로젝트 중 하나의 스크립트에서 도움이 될만한 전체 예제가 있습니다.이 파일을 "all_source"(실행 파일로 표시)라고 부르고 프로젝트의 루트 디렉토리에 넣은 다음 grep myfunc $(./all_source)스크립트의 끝에서 정렬 하는 것처럼 완전히 호출합니다. 선택 과목.

#!/bin/bash

find . \
    -type d \( \
            -wholename './lib' -o \
            -wholename './vc6' -o \
            -name 'gen' -o \
            -name '.svn' \
            \) -prune -o \
    -type f \( \
            -name '*.h' -o \
            -name '*.cpp' -o \
            -name '*.c' -o \
            -name '*.lua' -o \
            -name '*.*awk' \) -print \
    | sort

이 스크립트는 프로젝트 일치하는 모든 파일 이름을 반환 *.h, *.cpp, *.c, *.lua, *.*awk하지만, 모든을 .svn라는 이름의 폴더와 세대 폴더에서 검색뿐만 아니라에 대한 폴더를 건너 뛰는하지 않습니다 ./lib./vc6(만 사람 바로 프로젝트 루트 오프). 그래서 당신이 grep myfunc $(./all_source)그것을 할 때 그 파일들만 잡습니다. 프로젝트의 루트 디렉토리에서도 이것을 호출해야합니다.


0

찾을 수있는 -prune 옵션도 있습니다 :

 find . -path "*/.svn*" -prune -o -not -type d -exec grep -ni "myfunc" {} \; -print

0

당신은 이것을 시도 할 수 있습니다 :

grep -R  "myfunc" . | grep -v path_to_exclude/

예 : 로그 파일에서 컨텐츠를 검색하지 않으려면 다음을 수행하십시오.

grep -R "myfunc" . | grep -v log/
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.