디렉토리 아래에있는 모든 파일을보다 간단하게 잡을 수있는 방법이 있습니까?


21

일부 내용에 대해 전체 트리를 검색하고 싶을 때

find . -type f -print0 | xargs -0 grep <search_string>

성능 또는 간결성 측면에서이를 수행하는 더 좋은 방법이 있습니까?


2
@Downvoter : 우려 사항을 공유 할 수 있다면이 질문을 기꺼이 개선하십시오.
Dancrumb

2
많은 찾기 버전에는 xargs가 내장되어 있습니다 : find. -type f -exec fgrep <search_string> {} +
simpleuser

답변:


42

귀하의 grep지원 -r옵션 ( 재귀 )을 확인하십시오 .

grep -r <search_string> .

1
네 ... 방금 stackoverflow.com/questions/16956810/…을 찾았 습니다. 그 대답도 있습니다.
Dancrumb

--exclude-dir성능 문제를 해결하기 위해 의견을 추가하면 당첨자가 있습니다!
Dancrumb

1
이것은 이식성이 없지만 grep최근 FreeBSD 및 Linux 배포판에서 지원합니다. 왜 --exclude-dir? 전체 트리검색 하도록 요청하지 않았습니까 ?
Philippos

페어 포인트 ... --exclude-dir실제로 내 유스 케이스에서 유용합니다 (하위 트리의 일부는 크지 만 쓸모가 없기 때문에). 성능에 대해 묻었지만 ... 그렇습니다. 필요하지는 않습니다.
Dancrumb

이 경우 IIRC --exclude-dir가 GNU 전용 이라는 것을 추가해야 grep합니다. (-:
Philippos

13

하위 최적 대답 대신의 출력 배관의 find로는 grep, 당신은 실행할 수 있습니다

find . -type f -exec grep 'research' {} '+'

그리고 voila, 두 개 대신 하나의 명령!

설명 :

find . -type f

에서 모든 일반 파일을 찾으십시오.

-exec grep 'research'

grep '연구'

{}

찾은 파일 이름에서

'+'

파일 이름 당 한 번이 아니라 모든 파일 이름 당 하나의 명령을 사용하십시오.

Nb : ';'파일 이름 당 한 번 있었을 것입니다.

그 외에도 소스 코드를 처리하는 데 사용하면 ack코드 비트를 쉽게 찾을 수 있도록을 살펴볼 수 있습니다.

ack

편집하다 :

그 연구를 조금 확장 할 수 있습니다. 먼저 -name ''스위치를 사용하여 find지정된 이름 지정 패턴을 가진 파일을 찾을 수 있습니다.

예를 들면 :

  • 로그에 해당하는 파일 만 : -name '*.log'

  • c 헤더에 해당하는 파일 만 있지만 파일 이름 확장자는 대문자 또는 소문자로 지정할 수 없습니다. -iname *.c

주의 :에 같은 grepack-i스위치는이 경우의 경우를 구분을 의미한다.

이 경우 grep은 색상과 줄 번호없이 표시됩니다.

--color-n스위치 (각각 파일의 색상 및 줄 번호) 를 사용하여 변경할 수 있습니다 .

결국, 당신은 다음과 같은 것을 가질 수 있습니다 :

find . -name '*.log' -type f -exec grep --color -n 'pattern' {} '+'

예를 들어

$ find . -name '*.c' -type f -exec grep -n 'hello' {} '+' 
./test2/target.c:1:hello

5
ack대단한, 그리고 더 빠른 버전 ackIS ag(실버 수색자, geoff.greer.fm/ag )
cfeduke

1
나는 -name '*.log'그것이 더 빠르다는 것과 같은 필터로 이것을 선호합니다 .
sdkks

@cfeduke 내가 (당신이 가지고 무엇에 일하러!) AG의 WSL에 기본 APT 저장소의 일부가 대부분 때문에, 그것을 시도하지 않은
피에르 앙투안 기욤

트릭은 / dev / null을 grep에 추가하여 파일 이름을 표시하는 것입니다.
ChuckCottrill

트릭은 디렉토리 만 검색 한 다음 -exec grep / dev / null {} / *를 사용하여 디렉토리 당 단일 포크 / exec가있는 모든 파일을 가져 오는 것입니다.
ChuckCottrill

12

하위 디렉토리로 재귀화하려는 경우 :

grep -R 'pattern' .

-R옵션은 표준 옵션이 아니지만 가장 일반적인 grep구현에서 지원됩니다 .


7
GNU grep과 관련하여 심볼릭 링크를 건너 뛰는 -r대신 사용하십시오-R
αғsнιη

1
@AFSHIN 왜 심볼릭 링크를 따르고 싶지 않습니까?
Kusalananda

4
@Kusalananda Recursion? 현재의 GNU grep구현은 재귀를 포착 하지만 생각합니다. 그렇지 않으면 "트리"의 의미에 따라 다릅니다.
Philippos

2
@Philippos IMHO, 사용자를 돌보는 것은 도구가 grep해야 할 일 이 아닙니다 . 만약 사용자가 디렉토리 구조에 심볼릭 링크 루프를 가지고 있다면 그것은 사용자의 문제입니다. :-)
Kusalananda

3
@Kusalananda 그리고 시스템이 루프를 제공한다면? 절대로 길을 잃지 /sys/devices/cpu/subsystem/devices/cpu/subsystem/devices/cpu/...않았습니다 (-XI가 나를 돌보는 도구와 같이 (이상한 마법을 제공하지 않는 한 "AI"라고 부릅니다)) (-;
Philippos

5

상술 된 바와 같이 -r또는 -R(원하는 심볼릭 처리에 의존하는) 짧은 옵션이다.

그러나 -d <action>때때로 유용 할 수 있습니다.

좋은 점은 -d건너 뛰기 명령으로, 현재 레벨을 스캔하고 싶을 때 "grep : directory_name : 디렉토리입니다"를 침묵시킵니다.

$ grep foo * 
grep: q2: Is a directory 
grep: rt: Is a directory 

$ grep -d skip foo *  
$ 

그리고 물론 :

$ grep -d recurse foo * 
(list of results that don't exist because the word foo isn't in our source code
and I wouldn't publish it anyway).  
$ 

-d skip옵션은 다른 스크립트에서 정말 편리하므로 반드시 할 필요는 없습니다 2> /dev/null. :)


0

많은 파일을 처리하는 경우 하위 폴더의 모든 파일을 가져 오는 대신 검색해야하는 파일을 정리하면 grep이 더 빨리 실행됩니다.

때때로이 형식을 사용합니다.

grep "primary" `find . | grep cpp$`

의 하위 폴더에있는 모든 파일을 찾기 .에이를 cpp. 그런 다음 해당 파일을 "1 차"로 grep하십시오.

원하는 경우 해당 결과를 계속해서 grep 호출로 파이프 할 수 있습니다.

grep "primary" `find . | grep cpp$` | grep -v "ignoreThis" | grep -i "caseInsensitiveGrep"

1
backtics는 현대의 좋은 습관이 아니며 모두 쓸모가 없습니다
Christopher

1
이름에 특수 문자가 포함 된 파일이 있으면 중단됩니다. 나는 이것이 그대로 작동하기에 너무 특별하기 위해 얼마나 특별 해야하는지 모르겠지만, 당신이하고있는 일은 실제로 ls의 출력을 파싱하는 것과 똑같습니다.
CVn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.