재귀 적으로 grep하는 방법은 무엇입니까?


1682

grep모든 디렉토리와 하위 디렉토리를 재귀 적으로 어떻게합니까 ?

find . | xargs grep "texthere" *

110
@ TC1 슬픈 점은 grep 자체가 질문에 대답 할 수 있다는 것입니다 (최소한 GNU grep) : grep --help | grep 재귀
Frank Schmitt

7
grep을 자주 사용하여 재귀 적 검색을 수행하는 경우 (특히 수동으로 많은 파일 / 디렉토리 제외를 수행하는 경우) ack (매우 프로그래머에게 친숙한 grep 대안)이 유용 할 수 있습니다.
Nick McCurdy

19
실제로 직장에서 사용하는 Solaris 상자에서 -r 또는 --recursive 작업은 수행하지 않습니다. 그리고 grep 매뉴얼 페이지에는 재귀에 대한 언급이 없습니다. 나는 스스로 찾아서 몸을 굽히기 위해 의지해야했다.

8
Ag이 지금 할 수있는 나의 마음에 드는 방법입니다 github.com/ggreer/the_silver_searcher
dranxo

1
grep -rin xlsx *.plRedhat Linux에서 작동하지 않습니다. "일치하지 않음"오류가 발생합니다.
Bulrush

답변:


2507
grep -r "texthere" .

첫 번째 매개 변수는 검색 할 정규식을 나타내고 두 번째 매개 변수는 검색 할 디렉토리를 나타냅니다. 이 경우 .현재 디렉토리를 의미합니다.

참고 : 이것은 GNU grep에서 작동하며 Solaris와 같은 일부 플랫폼에서는 레거시 구현과 달리 GNU grep을 사용해야합니다. Solaris의 경우 이것이 ggrep명령입니다.


39
참고 : "grep -r"은 최신 grep에서만 작동합니다. AIX 5.3예를 들어 함께 제공되는 grep에서는 작동하지 않습니다 .
원천 징수

110
심볼릭 링크를 따르려면 grep -R을 사용하십시오.
Eloff

53
"-i"는 대소 문자를 구분하지 않으며 "-n"에는 일치하는 각 결과에 대한 줄 번호도 포함됩니다.
Sadegh

24
또한 정규식이 아닌 고정 문자열을 찾고 있다면 -F 옵션을 사용하십시오. 정규식 파서를 호출하지 않으면 시간을 절약 할 수 있습니다. 많은 파일을 검색하는 경우 매우 편리합니다.
Jeff

6
별명 rgrep = '그렙 -r'
totten

679

원하는 파일의 확장자 나 패턴을 알고 있다면 다른 방법으로 --include옵션 을 사용하는 것입니다.

grep -r --include "*.txt" texthere .

제외 할 파일을 언급 할 수도 있습니다 --exclude.

Ag

코드를 자주 검색하는 경우 Ag (The Silver Searcher) 는 grep보다 훨씬 빠른 대안이며 코드 검색에 맞게 사용자 정의됩니다. 예를 들어, 기본적으로 재귀 적이며에 나열된 파일과 디렉토리를 자동으로 무시 .gitignore하므로 grep 또는 find에 동일한 성가신 제외 옵션을 계속 전달할 필요가 없습니다.


3
Linux 및 Cygwin과 함께 제공되는 grep과 함께 작동하지만 AIX와 함께 제공되는 것은 아닙니다.
원천 징수

1
@KrzysztofWolny :``대신 =우분투에서 잘 작동합니다. 추신 : 그것은 역행 된 공간이어야하지만 SO 마크 다운 파서는 실패했습니다.
Dan Dascalescu

4
@ DanDascalescu 나는 grepAg가 아니라을 위해 찬성했다 . 그냥 알다시피 :)
Bernhard

1
재귀 적으로 검색하는 동안 디렉토리를 제외 할 수있는 옵션이 있습니까?
Tom Taylor

윈도우 Cygwin에서이 따옴표를 좋아하는--include "*.txt" --include "*.TXT"
밥 스타에게

127

또한:

find ./ -type f -print0 | xargs -0 grep "foo"

그러나 grep -r더 나은 대답입니다.


14
또는 파일 이름의 공백에 대해 걱정하지 않으려는 find . -type f -exec grep "foo" '{}' \;경우 지원되는 곳에서 잘 작동합니다.
Edd Steel

4
xargs를 통해 찾기를 grep으로 파이프하고 고정 문자열 만 검색하는 경우 (예 : 정규식이 아닌 경우) grep -F 옵션을 호출하면 grep이 정규식 엔진을로드하지 않습니다. 각 호출에 대해. 파일이 많으면 훨씬 빠릅니다.
Jeff

2
찾기 . -type f -exec grep -Hu "foo"{} \; 파일 이름을 제공하므로 사용하는 것입니다.
Wes

그것은 모든 * nix에서 스크립트에이 작품 때문에 POSIX 7
치로 틸리冠状病毒审查六四事件法轮功

1
find ./ -type f -print0 | xargs -0 grep "foo"
aehlke

118

나는 항상 항상 사용합니다 (Windows에서도 GoW-Windows의 Gnu ).

grep --include="*.xxx" -nRHI "my Text to grep" *

여기에는 다음과 같은 옵션이 포함됩니다.

--include=PATTERN

일치하는 파일 만 검색하는 디렉토리에서 반복합니다 PATTERN.

-n, --line-number

각 출력 행 앞에 입력 파일 내의 행 번호를 붙여 넣으십시오.

(참고 : phuclv주석 을 추가 하여 -n성능을 크게 저하 시키므로 해당 옵션을 건너 뛸 수 있습니다)

-R, -r, --recursive

각 디렉토리 아래의 모든 파일을 재귀 적으로 읽으십시오. 이것은 -d recurse옵션 과 동일합니다 .

-H, --with-filename

일치하는 파일 이름을 인쇄하십시오.

-I     

일치하는 데이터가없는 것처럼 이진 파일을 처리하십시오.
이것은 --binary-files=without-match옵션 과 동일합니다 .

대소 문자를 구분하지 않는 결과를 원하면 ' i'( -nRHIi)를 추가 할 수 있습니다 .

나는 얻을 수 있습니다 :

/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43:            'git.hidden'      => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21:            $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32:        $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20:    protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170:     * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176:        return $this->hidden;
...

Gow는 내가 사용하고있는 GNU Windows 유틸리티보다 새로운 것으로 보입니다. 지금 시도 중 ...
Radim Cernej

마지막 문자 *의 의미는 무엇입니까?
lorniper

2
@lorniper는 쉘이 현재 디렉토리의 모든 파일과 폴더를 선택하게하여 grep을 해당 파일에 적용하고 ( -R옵션으로 인해 재귀 적으로 ) 폴더에 적용합니다.
VonC

2
@lorniper 노이 정확히 : *.: (쉘에 의해 해석)을 글로브 패턴입니다 unix.stackexchange.com/a/64695/7490가 . ' .'dotfiles를 선택하거나 아니라 (등 폴더를 점합니다 .git/)
VonC

이전에는 항상 사용 grep -rnI했지만 -n성능이 많이 저하 된다는 사실을 알게 되었기 때문에 실제로 필요할 때만 사용하고 정상적으로 사용할 것입니다.-rI
phuclv

25

POSIX 시스템에서, 당신은 찾을 수 없습니다 -r에 대한 매개 변수를 grep당신의 grep -rn "stuff" .의지가 실행되지, 그러나 당신이 사용하는 경우 find명령을 그것은 것입니다 :

find . -type f -exec grep -n "stuff" {} \; -print

로 합의 Solaris하고 HP-UX.


{}의 의미는 무엇입니까? -각각 인쇄?
user1169587

3
에서 -exec옵션 - 기호는 {}현재에 의해 발견 된 파일 이름에 대한 참조입니다 find(우리가 발견 한 파일 이름으로 뭔가를 할 것입니다) 도구는 또한 -exec옵션은 종료되어야한다 ;이 모든 때문에합니다 (간부 명령의 종료 마크) 기호 만, 쉘에서 실행되면 해당 기호를 이스케이프해야합니다. 마지막으로 -print옵션을 사용 find하면 화면에서 찾은 파일 이름을 인쇄 할 수 있습니다.
rook

19

globbing **

grep -r작품을 사용 하지만 특히 큰 폴더에서는 과잉 일 수 있습니다.

보다 실용적인 사용법을 위해 globbing 구문 ( **) 을 사용하는 구문은 다음과 같습니다.

grep "texthere" **/*.txt

패턴이 선택된 패턴으로 특정 파일 만 잡습니다. Bash +4 또는 zsh 와 같은 지원되는 쉘에서 작동합니다 .

이 기능을 활성화하려면 다음을 실행하십시오 shopt -s globstar..

참조 : 어떻게 리눅스에서 특정 텍스트를 포함하는 모든 파일을 찾을 수 있습니까?

git grep

Git 버전 관리하에있는 프로젝트의 경우 다음을 사용하십시오.

git grep "pattern"

훨씬 빠릅니다.

ripgrep

대규모 프로젝트의 경우 가장 빠른 ripgrep그 리핑 도구는 기본적으로 파일을 재귀 적으로 그 리핑하는 것입니다.

rg "pattern" .

이 시스템 은 유한 오토마타, SIMD 및 공격적인 리터럴 최적화를 사용하여 검색 속도를 높이는 Rust의 정규식 엔진 위에 구축되었습니다 . 여기 에서 자세한 분석을 확인 하십시오 .


3
git grep 제안에 감사드립니다. 매우 유용하며 몰랐습니다!
Basya

2
ripgrep 제안에 감사드립니다. 더 빠릅니다.
멋진 것

11

의 이름을 찾으려면 files과 함께 path반복적으로 특정 포함 string에 대한 명령 아래 사용 UNIX:

find . | xargs grep "searched-string"

에 대한 Linux:

grep -r "searched-string" .

UNIX서버 에서 파일을 찾으십시오

find . -type f -name file_name

LINUX 서버에서 파일을 찾으십시오

find . -name file_name

11

파일 이름 만 유용 할 수 있습니다.

grep -r -l "foo" .

10

심볼릭 링크가 아닌 실제 디렉토리 만 따르려면

grep -r "thingToBeFound" directory

실제 디렉토리뿐만 아니라 심볼릭 링크를 따르려면 (무한 재귀에주의하십시오),

grep -R "thing to be found" directory

재귀 적으로 grep하려고 시도하기 때문에 다음 옵션도 유용 할 수 있습니다.

-H: outputs the filename with the line

-n: outputs the line number in the file

따라서 현재 디렉토리 또는 하위 디렉토리에서 Darth Vader를 포함하는 모든 파일을 찾고 파일 이름과 행 번호를 캡처하지만 재귀가 기호 링크를 따르지 않게하려면 명령은 다음과 같습니다.

grep -rnH "Darth Vader" .

디렉토리에서 cat이라는 단어에 대한 모든 언급을 찾으려면

/home/adam/Desktop/TomAndJerry 

그리고 당신은 현재 디렉토리에 있습니다

/home/adam/Desktop/WorldDominationPlot

문자열 "cats"인스턴스의 줄 번호가 아닌 파일 이름을 캡처하고 재귀가 심볼릭 링크를 찾으면 다음 링크 중 하나를 실행할 수 있습니다.

grep -RH "cats" ../TomAndJerry                   #relative directory

grep -RH "cats" /home/adam/Desktop/TomAndJerry   #absolute directory

출처:

"grep --help"실행

https://www.nixtutor.com/freebsd/understanding-symbolic-links/ 이 답변을 읽고 혼란스러워하는 사람을위한 상징적 링크에 대한 짧은 소개


좋은 대답입니다. 여분의 스위치 (-rnh)는 매우 유용하므로 제안 해 주셔서 감사합니다.
semtex41

8

ag는 github.com/ggreer/the_silver_searcher에서 가장 좋아하는 방법 입니다. 기본적으로 ack와 동일하지만 몇 가지 최적화가 더 있습니다.

짧은 벤치 마크입니다. 각 테스트 전에 캐시를 지우십시오 (cf /ubuntu/155768/how-do-i-clean-or-disable-the-memory-cache 참조 )

ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .

real    0m9.458s
user    0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .

real    0m6.296s
user    0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .

real    0m5.641s
user    0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache

real    0m0.154s
user    0m0.224s
sys 0m0.172s


6

디렉토리 구조에서 모든 파일의 특정 컨텐츠를 찾고 있다면, find수행중인 작업이 더 명확 하기 때문에 사용할 수 있습니다 .

find -type f -exec grep -l "texthere" {} +

하는 것으로 -l(L의와 downcase) 텍스트가 포함 된 파일의 이름을 표시합니다. 대신 매치 자체를 인쇄하려면 제거하십시오. 또는 -H파일을 일치 항목과 함께 가져 오는 데 사용 하십시오. 모두 함께 다른 대안은 다음과 같습니다.

find -type f -exec grep -Hn "texthere" {} +

어디에서 -n줄 번호를 출력합니다.


2
와 함께 사용하는 대신 find불필요한 사용 xargs과 사용을 피할 수 있는 유일한 솔루션 으로 많은 찬사를 받았습니다 . :-)+\;-exec
ShadowRanger 2016 년

6

이것은 현재 컴퓨터에서 내 경우 (Windows 7의 git bash)에서 작동 한 것입니다.

find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"

공백이있는 경로의 경우 항상 -print0 및 -0을 잊어 버립니다.

편집 : 내가 선호하는 도구는 이제 ripgrep입니다 : https://github.com/BurntSushi/ripgrep/releases . 정말 빠르며 더 나은 기본값이 있습니다 (기본적으로 재귀 적과 같은). 내 원래 답변과 동일하지만 ripgrep을 사용하는 예 :rg -g "*.cs" "content pattern"


4

grep -r "texthere" . (종료 통지 기간)

(^ 신용 : https://stackoverflow.com/a/1987928/1438029 )


설명:

grep -r "texthere" /( 모든 디렉토리와 하위 디렉토리를 재귀 적으로 grep )

grep -r "texthere" .( 디렉토리와 서브 디렉토리를 재귀 적으로 grep )

반복 재귀

grep [options] PATTERN [FILE...]

[옵션]

-R, -r, --recursive

각 디렉토리 아래의 모든 파일을 재귀 적으로 읽으십시오.

이것은 -d recurse또는 --directories=recurse옵션 과 같습니다 .

http://linuxcommand.org/man_pages/grep1.html

grep help

$ grep --help

$ grep --help |grep recursive
  -r, --recursive           like --directories=recurse
  -R, --dereference-recursive

대안

ack( http://beyondgrep.com/ )

ag( http://github.com/ggreer/the_silver_searcher )


4

2018 년, 당신은 사용하려는 ripgrep또는 the-silver-searcher그들이 있기 때문에 빠른 방법은 대안보다.

다음은 336 개의 1 차 서브 디렉토리가있는 디렉토리입니다.

% find . -maxdepth 1 -type d | wc -l
     336

% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py'  1.24s user 2.23s system 283% cpu 1.222 total

% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$'  2.71s user 1.55s system 116% cpu 3.651 total

% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py'  1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs  6.65s user 0.49s system 32% cpu 22.164 total

OSX에서이 설치 ripgrep: brew install ripgrep. 설치 silver-searcher: brew install the_silver_searcher.


이 작업을 자주 수행해야하는 경우 속도가 중요하지만 대부분의 사용자는 1 년에 몇 번만이 작업을 수행합니다. 최신 스파이어 타사 Juju 도구 du jour를 설치하는 것은 과도하며 1978 년 이후 크게 변하지 않은 솔루션은 관계없이 알 수 있습니다.
tripleee

프로그래머가 소스 트리에서 일년에 몇 번만 텍스트를 검색한다는 것은 타당하지 않습니다. 그러나 사용성 측면에서도 rg재귀 grep 명령을 처음부터 결합하는 데 상당한 이점이 있습니다. 사용 rg: rg foo. 유닉스 도구 사용 : find . | xargs grep foo. 파일에 따옴표가 있으면을 사용해야 find . -print0 | xargs -0 grep foo합니다. 당신이 일년에 몇 번 이것을 사용한다면 기억할 것입니까?
hughdbrown

1
find . -type f -exec grep 'regex' {} +이러한 도구를 규칙적으로 사용하면 실제로 기억하기 쉬운 것을 잊어 버릴 것 입니다. 하지만 아마 당신은 실행해야 ctags또는 etags자주 물건을 찾을 필요가있는 경우 소스 트리 어쨌든합니다.
tripleee

나는 ripgrep을 사용하고 있으며 훌륭합니다. 그러나 실버 검색기는 프로그래머에게 환상적입니다. +1
Matt

3

IBM AIX 서버 (OS 버전 : AIX 5.2)에서 다음을 사용하십시오.

find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \; 

이렇게하면 경로 / 파일 이름과 상대 줄 번호가 파일에 인쇄됩니다.

./inc/xxxx_x.h

2865 : / ** 설명 : stringYouWannaFind * /

어쨌든, 그것은 나를 위해 작동합니다 :)


3

다음은 검색 A에 대한 명령입니다 String에 재귀 적 UnixLinux환경.

에 대한 UNIX명령입니다 :

find . -name "string to be searched" -exec grep "text" "{}" \;

에 대한 Linux명령입니다 :

grep -r "string to be searched" .

2

사용 가능한 플래그 목록 :

grep --help 

현재 디렉토리 의 정규 표현식 텍스트 와 일치하는 모든 줄을 해당 줄 번호와 함께 반환합니다 .

grep -rn "texthere" .

루트 디렉토리에서 시작하여 해당 행 번호와 대소 문자를 무시하고 texthere 에 대한 모든 일치 항목을 리턴합니다 .

grep -rni "texthere" /

여기에 사용 된 플래그 :

  • -r 재귀
  • -n 출력 라인 번호 인쇄
  • -i 대소 문자 무시

1

나는 이것이 당신이 작성하려고하는 것 같아요

grep myText $(find .)

grep 파일을 찾으려면 다른 도움이 될 수 있습니다.

grep myText $(find .) | cut -d : -f 1 | sort | uniq

매우 직관적입니다 : 예 : grep -i acc $ (find. -name "execution *. *")
Yu Shen

1

여기에 내 두 센트를 던져. 다른 사람들이 이미 언급했듯이 grep -r 이 모든 플랫폼에서 작동하지는 않습니다. 이것은 바보처럼 들릴 수 있지만 항상 git을 사용합니다.

git grep "texthere"

디렉토리가 스테이징되지 않더라도 스테이징하고 git grep을 사용합니다.


0

참고 find . -type f | xargs grep whatever발견 일치 너무 많은 파일이있는 경우 솔루션의 종류의 오류 "긴에 인수 목록"으로 실행됩니다.

가장 좋은 방법은 grep -r사용할 수 없다면 find . -type f -exec grep -H whatever {} \;대신 사용하십시오.


응? xargs특히 "인수 목록이 너무 깁니다"문제에 대한 해결 방법입니다.
tripleee

2
음, 더 - xargs를가 없습니다 특히 아글리스트에 인수 파이프를 변환하지만, 예, 그것은 현대 xargs를 그 사실 및 / 또는 -L이 -s와 함께 사용하면 매우 긴 arglists를 해결할 수있는 여러 명령 호출에 침입에 의해하지만, 기본적으로 구성되지 않았으며 위의 응답에 없었습니다. 예를 들면 다음과 같습니다.find . -type f | xargs -L 100 grep whatever
m.thome

어떤 플랫폼에 있습니까? POSIXxargs 는이 동작을 즉시 사용할 수 있도록 표준화되었습니다. " xargs유틸리티는 명령 행이 호출 될 때 결합 된 인수 및 환경 목록이 {ARG_MAX} -2048 바이트를 초과하지 않도록 명령 행 길이를 제한해야합니다."
tripleee

흠. gnu 문서는이 기준으로 posix보다 명확하지 않으며 더 이상이 진술을 한 기계에 액세스 할 수 없지만 현재 구현에 대한 원래 해석을 확인할 수는 없습니다. 물론 재귀 grep이 여전히 바람직하지만 xargs 레시피를 피할 이유가 거의 없습니다 (grep의 최종 호출이 단일 파일 이름 만 전달되는 것을 피하려면 grep에 -H를 사용하십시오).
m.thome

0

@christangrant 답변이 너무 입력하기 어려운 경우 재미를 위해 * .txt 파일을 빠르고 더러운 검색 :-)

grep -r texthere .|grep .txt


0

다음은 주어진 폴더 ($ 1)의 모든 하위 폴더를 통과하고 grep주어진 파일 ($ 2)에서 주어진 문자열 ($ 3)에 대한 검색을 사용하는 재귀 (bash 및 sh로 가볍게 테스트 됨) 기능입니다 .

$ cat script.sh
#!/bin/sh

cd "$1"

loop () {
    for i in *
    do
        if [ -d "$i" ]
        then
            # echo entering "$i"
            cd "$i"
            loop "$1" "$2"
        fi
    done

    if [ -f "$1" ]
    then
        grep -l "$2" "$PWD/$1"
    fi

    cd ..
}

loop "$2" "$3"

실행 및 예제 출력 :

$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename

-2
The syntax is:
cd /path/to/dir
grep -r <"serch_word name"> .

7
이것은 다른 답변에 많이 추가되지 않습니다
Mel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.