grep --exclude /-include 구문을 사용하여 특정 파일을 grep하지 마십시오.


780

foo=디렉토리 트리에서 텍스트 파일 의 문자열 을 찾고 있습니다. 일반적인 Linux 컴퓨터에 bash 쉘이 있습니다.

grep -ircl "foo=" *

디렉토리에는 또한 "foo ="와 일치하는 많은 바이너리 파일이 있습니다. 이 결과는 관련이 없으며 검색 속도가 느리기 때문에 grep이 이러한 파일 (대부분 JPEG 및 PNG 이미지) 검색을 건너 뛰고 싶습니다. 어떻게해야합니까?

나는이 알고 --exclude=PATTERN--include=PATTERN옵션,하지만 패턴 형식은 무엇입니까? grep의 맨 페이지는 다음과 같이 말합니다.

--include=PATTERN     Recurse in directories only searching file matching PATTERN.
--exclude=PATTERN     Recurse in directories skip file matching PATTERN.

에 검색 그렙 포함 , 포함, 제외 그렙 , 제외 GREP 및 변종 관련 내용을 찾지 못 하셨나요

특정 파일에만 더 좋은 방법이 있다면 나는 전부입니다. 문제가되는 파일을 이동하는 것은 옵션이 아닙니다. 특정 디렉토리 만 검색 할 수 없습니다 (디렉토리 구조는 모든 곳에서 모든 것이 엉망입니다). 또한 아무것도 설치할 수 없으므로 일반적인 도구 ( grep 또는 제안 된 find 와 같은 )와 관련이 있습니다.


13
그냥 참고로, 인수가 사용 : 만 일치하는 파일을 재귀 -r 보여 파일 -i 대소 문자를 구별하지 -l의 일치를 계산 -c
Piskvor 건물 왼쪽

68
svn dirs를 배제하는 더 빠른 방법은 --exclude-dir=.svn, 그래서 grep은 전혀 들어 가지 않습니다
orip

25
사람들이 알아야 할 몇 가지 지적 사항 : 1. 여기에 글 머리 기호가없는 것에주의하십시오 : --exclude = ' . {png, jpg}'grep 때문에 (적어도 나의 GNU grep 버전에서는) 작동하지 않습니다 globs에서 {}을 지원하지 않습니다. 위의 내용은 '--exclude = .png --exclude = *. jpg' 로 셸 확장됩니다 (cwd에서 일치하는 파일이 없다고 가정하면 일반적으로 '--exclude ='로 파일 이름을 시작하지 않기 때문에 가능성이 거의 없습니다). grep은 괜찮습니다. 2. --exclude는 GNU 확장이며 POSIX의 grep 정의의 일부가 아니므로이를 사용하여 스크립트를 작성하는 경우 반드시 비 GNU 시스템에서 실행되지는 않습니다.
ijw

2
exclude-dir 사용법의 전체 예 :grep -r --exclude-dir=var "pattern" .
Tisch

답변:


767

쉘 글 로빙 구문을 사용하십시오.

grep pattern -r --include=\*.{cpp,h} rootdir

의 구문 --exclude은 동일합니다.

별표는 백 슬래시로 이스케이프되어 셸에서 별표가 확장되는 것을 방지합니다 (예 --include="*.{cpp,h}": 등도 인용 ). 당신이 패턴과 일치하는 현재 작업 디렉토리에있는 파일이 있다면처럼 그렇지 않으면, 명령 줄 뭔가를 확장 할 grep pattern -r --include=foo.cpp --include=bar.h rootdir경우에만라는 이름의 파일을 검색 할 것이다, foo.cpp그리고 bar.h당신이 원하는 것을 매우 가능성이 없습니다이다.


8
이유를 모르겠지만 다음과 같은 포함 패턴을 인용해야했습니다.grep pattern -r --include="*.{cpp,h}" rootdir
topek

6
@topek : 좋은 점-현재 디렉토리에 .cpp / .h 파일이 있으면 쉘은 grep을 호출하기 전에 glob를 확장하므로 grep pattern -r --include=foo.cpp --include=bar.h rootdir파일 과 같은 명령 줄이 생깁니다. 이름 foo.cpp또는 bar.h. 현재 디렉토리의 glob와 일치하는 파일이없는 경우 쉘은 glob를 grep으로 전달하여 올바르게 해석합니다.
Adam Rosenfield

6
방금 glob이 파일 이름 만 일치시키는 데 사용된다는 것을 깨달았습니다. 전체 디렉토리를 제외하려면 --exclude-dir옵션이 필요합니다 . 동일한 규칙이 적용됩니다. 경로가 아닌 디렉토리 파일 이름 만 일치합니다.
Krzysztof Jabłoński

3
--include후에 작동하지 않는 것 같습니다 --exclude. 코드를 검색하고 라이브러리를 무시하고 파일 및 스왑을 무시하는 데 사용하는 및 alias의 긴 목록을 grep 해야한다는 점을 제외하고는 시도조차도 의미가 없다고 생각합니다 . 나는 그것이 효과가 있기를 바 랐기 때문에 내 것으로 만 제한 할 수 있었지만 .foo 파일이 아닌 모든 것을 무시 하고 포함 하는 것으로 보입니다 . 의 순서 스와핑 및 내에 도움이되지 작품,하지만 슬프게도을 . --exclude--exclude-dirgrep -r --exclude='*.foo' --include='*.bar'alias--include='*.bar'--include--include--excludealias
Michael Scheper

1
이 규칙을 얻기 위해 다른 사람의 마음을 어떻게 읽을 수 있습니까 PATTERN? 반 시간 나는 그들이 무엇을 기다리고 있는지에 대한 설명을 찾을 수 없습니다
Arkady

221

이진 파일을 건너 뛰려면 -I(대문자 i) 옵션을 참조하십시오. 이진 파일은 무시합니다. 나는 정기적으로 다음 명령을 사용합니다.

grep -rI --exclude-dir="\.svn" "pattern" *

재귀 적으로 검색하고 이진 파일을 무시하며 원하는 패턴에 대해 Subversion 숨겨진 폴더를 찾지 않습니다. 나는 직장에서 내 상자에 "grepsvn"이라는 별칭을 사용했습니다.


1
고마워, 그것은 내가 겪은 다른 시나리오에 매우 유용합니다.
Piskvor가 건물을 떠났습니다.

25
--exclude-dir모든 곳에서 사용할 수 없습니다. GNU grep 2.5.1을 사용하는 RH 박스에는 없습니다.
gcb

--exclude-dir사용할 수없는 경우에 대한 제안 사항 이 있습니까? 나의 모든 시도에서, --exclude법안에 맞지 않는 것 같습니다.
JMTyler 2014 년

항상 GNU에서 최신 grep 소스를 다운로드하고 'configure; 하다; sudo make install '을 참조하십시오. 이것은 Mac 또는 이전 Linunx 배포에서 처음으로 수행하는 작업 중 하나입니다.
Jonathan Hartley

3
정확히 내가 필요한 것. 실제로는 git을 사용합니다. 그래서 --exclude-dir="\.git". :-)
Ionică Bizău

66

이러한 상황에 맞게 설계된 ack을 살펴보십시오 . 당신의 예

grep -ircl --exclude=*.{png,jpg} "foo=" *

ack로 수행됩니다.

ack -icl "foo="

ack은 기본적으로 이진 파일을 찾지 않으며 -r은 기본적으로 켜져 있습니다. CPP와 H 파일 만 원한다면

ack -icl --cpp "foo="

멋지게 보입니다. 다음 번에 독립형 Perl 버전을 사용해보십시오. 감사합니다.
Piskvor는 건물을 떠나

5
좋은 전화, 나는 더 이상 ack없이 살 수 없다.
기회

1
stackoverflow.com/questions/667471/…- 이것은 grep을 실행하는 곳이면 윈도우에서 ack를 얻을 수 있습니다.
TamusJRoyce

당신이 원하는 어쩌면 @Chance silversearcher-AG를 그냥 apt-get:) 우분투
Justme0

와 혼동하지awk
jasonleonhard

35

grep 2.5.3은 --exclude-dir 매개 변수를 도입하여 원하는 방식으로 작동합니다.

grep -rI --exclude-dir=\.svn PATTERN .

환경 변수를 설정할 수도 있습니다. GREP_OPTIONS = "-exclude-dir = .svn"

그래도 앤디가 ack에 대한 투표를 하겠습니다. 최고입니다.


7
정확한 버전 번호를 언급하면 ​​+1; grep 2.5.1이 있고 exclude-dir 옵션을 사용할 수 없습니다
James

25

오랜 시간이 지난 후에 이것을 발견하면 다음과 같이 여러 포함 및 제외를 추가 할 수 있습니다.

grep "z-index" . --include=*.js --exclude=*js/lib/* --exclude=*.min.js

5
--exclude = {pattern1, pattern2, pattern3}
Yasser Sinjab

12

제안 된 명령 :

grep -Ir --exclude="*\.svn*" "pattern" *

--exclude는 기본 이름에서 작동하기 때문에 개념적으로 잘못되었습니다. 다시 말해, 현재 디렉토리에서 .svn 만 건너 뜁니다.


3
네, 전혀 작동하지 않습니다. 나를 위해 일한 사람은 다음과 같습니다. exclude-dir = .svn
Taryn East

2
@Nicola 감사합니다! 왜 이것이 효과가 없는지 머리를 찢어 버렸습니다. 맨 페이지에서 이것을 발견 할 수있는 방법이 있습니까? "PATTERN"과 일치합니다. 여기에 설명 된 것처럼 EDIT 맨 페이지에 "파일"이라고 표시되어 있습니다. fixunix.com/unix/…
13ren

11

grep 2.5.1에서는 ~ / .bashrc 또는 ~ / .bash 프로필에이 줄을 추가해야합니다.

export GREP_OPTIONS="--exclude=\*.svn\*"

9

grepping grep의 출력이 때때로 매우 유용하다는 것을 알았습니다.

grep -rn "foo=" . | grep -v "Binary file"

그럼에도 불구하고 실제로 바이너리 파일을 검색하는 것을 막지는 못합니다.


10
grep -I이진 파일을 건너 뛰는 데 사용할 수 있습니다 .
Nathan Fellman

또한 내가 어렸을 때 ... 이제는 더 잘 알고 문제에 직면했을 때 가장 먼저 RTFM입니다
gcb

grep grep은 색상 하이라이트를 제거합니다.
Max Li

7

를 사용하지 않으려는 경우 기능이 find마음에 -prune듭니다.

find [directory] \
        -name "pattern_to_exclude" -prune \
     -o -name "another_pattern_to_exclude" -prune \
     -o -name "pattern_to_INCLUDE" -print0 \
| xargs -0 -I FILENAME grep -IR "pattern" FILENAME

첫 번째 행에서 검색하려는 디렉토리를 지정하십시오. .(현재 디렉토리)는 유효한 경로입니다.

2 층과 3 선, 사용에 "*.png", "*.gif", "*.jpg", 등. -o -name "..." -prune패턴이있는만큼 이러한 구성 을 많이 사용하십시오 .

네 번째 줄에는 다른 패턴 ( -o"또는"을 "로 지정" find)과 원하는 패턴이 필요하며 a -print또는 -print0끝에 있어야합니다. 당신은 남아있는 가지 치기 후 것을 "다른 모든"원하는 경우 *.gif, *.png등 이미지를 한 후 사용 -o -print0하고는 4 선으로 완료됩니다.

마지막으로 다섯 번째 줄에는 xargs결과 파일 각각을 가져 와서 변수에 저장 하는 파이프가 FILENAME있습니다. 그런 다음 grep, -IR플래그 를 전달한 "pattern"다음 FILENAME로 확장하여 xargs에서 찾은 파일 이름 목록이됩니다 find.

특정 질문에 대해서는 다음과 같은 진술이 나타날 수 있습니다.

find . \
     -name "*.png" -prune \
     -o -name "*.gif" -prune \
     -o -name "*.svn" -prune \
     -o -print0 | xargs -0 -I FILES grep -IR "foo=" FILES


내가 제안하는 한 가지 수정안 : -false각각 -prune을 사용하는 즉시 잊어 버리거나 사용을 잊어 버리거나 -print0어떤 종류의 exec명령을 사용하면 실제로 제외하려는 파일이 인쇄되지 않습니다 : -name "*.png" -prune -false -o name "*.gif -prune -false...
OnlineCop

7

CentOS 6.6 / Grep 2.6.3에서는 다음과 같이 사용해야합니다.

grep "term" -Hnir --include \*.php --exclude-dir "*excluded_dir*"

(그렇지 않으면 "="등호의 부족을 주목 --include, --exclude, include-dir그리고 --exclude-dir무시됩니다)


6

git grep

사용 git grep성능과 목적에 최적화되어 특정 파일을 검색 할 수 있습니다.

기본적으로 바이너리 파일을 무시하고 .gitignore. Git 구조로 작업하지 않는 경우에도을 전달하여 사용할 수 있습니다 --no-index.

구문 예 :

git grep --no-index "some_pattern"

자세한 예는 다음을 참조하십시오.


5

저는 허가를 받았지만 ~ / .bash_profile의 모습은 다음과 같습니다.

내보내기 GREP_OPTIONS = "-orl --exclude-dir = .svn --exclude-dir = .cache --color = auto"GREP_COLOR = '1; 32'

두 개의 디렉토리를 제외하려면 --exclude-dir을 두 번 사용해야했습니다.



3

비재 귀적으로 검색하는 경우 glop 패턴 을 사용 하여 파일 이름을 일치 시킬 수 있습니다 .

grep "foo" *.{html,txt}

html과 txt를 포함합니다. 현재 디렉토리에서만 검색합니다.

서브 디렉토리에서 검색하려면 다음을 수행하십시오.

   grep "foo" */*.{html,txt}

하위 하위 디렉토리에서 :

   grep "foo" */*/*.{html,txt}

3

디렉토리에는 또한 많은 이진 파일이 있습니다. 특정 디렉토리 만 검색 할 수 없습니다 (디렉토리 구조가 엉망입니다). 특정 파일에만 더 좋은 방법이 있습니까?

ripgrep

이것은 현재 디렉토리를 재귀 적으로 검색하도록 설계된 가장 빠른 도구 중 하나입니다. 그것은 효율성을 극대화하기 위해 Rust의 정규식 엔진 위에 빌드 된 Rust 로 작성되었습니다 . 여기 에서 자세한 분석을 확인 하십시오 .

따라서 다음을 실행할 수 있습니다.

rg "some_pattern"

당신을 존중합니다 .gitignore 하고 자동으로 숨겨진 파일 / 디렉토리 및 이진 파일을 건너 뜁니다.

-g/를 사용하여 파일 및 디렉토리를 포함하거나 제외 할 수 있습니다 --glob. 글 로빙 규칙은 .gitignore글롭 과 일치 합니다. 확인 man rg도움.

자세한 예 는 grep을 사용하여 특정 확장자와 일치하지 않는 일부 파일을 제외하는 방법을 참조하십시오.

macOS에서는을 통해 설치할 수 있습니다 brew install ripgrep.


3

찾기와 xargs는 당신의 친구입니다. grep의 --exclude 대신 파일 목록을 필터링하는 데 사용하십시오.

같은 것을 시도하십시오

find . -not -name '*.png' -o -type f -print | xargs grep -icl "foo="

이것에 익숙해지면 이점은 다른 비 사용 사례로 확장 가능하다는 것입니다.

find . -not -name '*.png' -o -type f -print | xargs wc -l

PNG가 아닌 파일을 모두 제거하려면

find . -not -name '*.png' -o -type f -print | xargs rm

기타

일부 파일 이름 사용에 공백이있을 수있는 경우로는, 코멘트에 지적 -print0하고 xargs -0대신.


1
공백이있는 파일 이름에서는 작동하지 않지만 print 대신 print0을 사용하고 xargs에 -0 옵션을 추가하면이 문제를 쉽게 해결할 수 있습니다.
Adam Rosenfield

2

그 스크립트는 모든 문제를 해결하지 못합니다 ... 이것을 더 잘 시도하십시오 :

du -ha | grep -i -o "\./.*" | grep -v "\.svn\|another_file\|another_folder" | xargs grep -i -n "$1"

이 스크립트는 "실제"정규식을 사용하여 디렉토리가 검색되지 않도록하기 때문에 훨씬 좋습니다. "\ |"로 폴더 또는 파일 이름을 구분하십시오. grep -v에서

즐기세요! 내 리눅스 쉘에서 발견! XD


2

@ 이것 좀 봐.

grep --exclude="*\.svn*" -rn "foo=" * | grep -v Binary | grep -v tags

2
대략 이것을 달성하는 것은 다른 게시물에서 다루어졌습니다. 또한 다양한 레이아웃 옵션을 설정하면 줄 번호와 같은 것을 엉망으로 만들거나 원하는 문맥 줄을 제외시킵니다.
Chris Morgan

여러 개의 "-v"옵션을 동시에 어떻게 사용할 수 있습니까?
개장

1

--binary-files=without-matchGNU에 옵션 grep은 바이너리 파일을 건너 뛸 가져옵니다. ( -I다른 곳에서 언급 한 스위치 와 동일합니다 .)

(최신 버전의 grep; 2.5.3 이상 이 필요할 수 있습니다 .)


1

tcsh .alias 파일에 적합 :

alias gisrc 'grep -I -r -i --exclude="*\.svn*" --include="*\."{mm,m,h,cc,c} \!* *'

{mm, m, h, cc, c} 부분이 따옴표 안에 들어가서는 안된다는 것을 알아내는 데 시간이 걸렸습니다. ~ 키이스


0

grep의 모든 이진 결과를 무시하려면

grep -Ri "pattern" * | awk '{if($1 != "Binary") print $0}'

awk 부분은 모든 바이너리 파일 foo와 일치하는 행을 필터링합니다.


-2

이 시도:

  1. --Fcurrdir 아래에 " " 라는 이름의 폴더를 만듭니다 . 또는 이름이 " --F"인 다른 폴더를 " "(으) 로 연결하십시오 double-minus-F.
  2. #> grep -i --exclude-dir="\-\-F" "pattern" *
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.